Перейти к содержанию

Уникальность данных

FUCKTAR предоставляет мощный механизм для обеспечения уникальности сгенерированных данных. В этом разделе мы рассмотрим, как использовать эту функцию.

Настройка уникальности

Для включения режима уникальности используйте метод configure(unique=True):

# Генерация уникальных пользователей
unique_users = (
    UserPatterns()
    .configure(unique=True)
    .generate(count=100)
)

Определение полей для уникальности

Уникальность определяется в конфигурации паттерна через параметр unique_fields:

class UserPatterns(BasePattern[User]):
    first_name = UserRuPatterns.first_name
    last_name = UserRuPatterns.last_name
    email = UserRuPatterns.email
    phone = UserRuPatterns.phone

    pattern_config = PatternConfig(
        scope="users",
        unique_fields=["email"]  # Уникальность по email
    )

Вы можете определить уникальность по нескольким полям:

class UserPatterns(BasePattern[User]):
    first_name = UserRuPatterns.first_name
    last_name = UserRuPatterns.last_name
    email = UserRuPatterns.email
    phone = UserRuPatterns.phone

    pattern_config = PatternConfig(
        scope="users",
        unique_fields=["email", "phone"]  # Уникальность по email и phone
    )

Композитная уникальность

FUCKTAR поддерживает композитную уникальность, когда уникальность определяется комбинацией нескольких полей:

class OrderPatterns(BasePattern[Order]):
    user_id = r"^\d{1,10}$"
    product_id = r"^\d{1,10}$"
    order_date = r"^(19|20)\d{2}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|2[0-8])$"

    pattern_config = PatternConfig(
        scope="orders",
        unique_fields=["user_id", "product_id"]  # Уникальность комбинации user_id и product_id
    )

Ограничения уникальности

При работе с уникальностью следует учитывать следующие ограничения:

  1. Уникальность проверяется только в рамках одного scope
  2. Уникальность сохраняется между сессиями генерации
  3. При достижении максимального числа попыток генерации может быть выброшено исключение UniqueGenerationError

Настройка параметров уникальности

Вы можете настроить параметры генерации уникальных данных:

users = (
    UserPatterns()
    .configure(unique=True, ignore_count=False)
    .generate(
        count=1000,
        max_attempts=100,  # Максимальное число попыток генерации уникального объекта
        timeout=30         # Таймаут в секундах
    )
)

Режим ignore_count

Если установить ignore_count=True, генератор вернет столько уникальных объектов, сколько удалось сгенерировать, даже если это меньше запрошенного количества:

users = (
    UserPatterns()
    .configure(unique=True, ignore_count=True)
    .generate(count=1000000, max_attempts=100)
)
# Может вернуть меньше 1000000 объектов, если не удалось сгенерировать больше

Обработка ошибок уникальности

При невозможности сгенерировать нужное количество уникальных объектов будет выброшено исключение UniqueGenerationError:

try:
    users = UserPatterns().configure(unique=True).generate(count=1000000, max_attempts=5)
except UniqueGenerationError as e:
    print(f"Не удалось сгенерировать уникальные данные: {e}")

Многопоточная уникальность

FUCKTAR обеспечивает безопасность уникальности в многопоточных приложениях благодаря использованию файловых блокировок:

import concurrent.futures

def generate_users_batch(count):
    return UserPatterns().configure(unique=True).generate(count=count)

# Генерация в нескольких потоках с сохранением уникальности
with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
    futures = [
        executor.submit(generate_users_batch, 100) 
        for _ in range(4)
    ]

    results = [future.result() for future in futures]

Очистка истории уникальности

Вы можете управлять историей уникальности:

from fucktar.storage import ScopeStorage

# Удаление истории для определенного scope
ScopeStorage.remove("users")

# Очистка всей истории
ScopeStorage.clear_all()

Это может быть полезно в тестах или при необходимости перегенерации данных.