Эффективный способ обновить экземпляры случайными значениями - PullRequest
0 голосов
/ 27 апреля 2020

Я использую Django с PostgreSQL, и я хочу знать, есть ли способ обновить определенное количество моделей, имеющих уникальные поля, случайными значениями.

Моя проблема Мне нужно обновить 5 тысяч пользователей, меняя его адреса электронной почты и имена пользователей случайными значениями. Эти поля уникальны, что означает, что два экземпляра не могут иметь одинаковые значения. Моя логика c такова: для каждого пользователя (1) генерировать случайную строку электронной почты, затем, если с таким адресом нет ни одного пользователя, используйте эту строку, иначе вернитесь к 1

# Python2.7 Django 1.11, but everything helps
from django.contrib.auth.models import User
from django.utils.crypto import get_random_string

for user in User.objects.order_by('-pk')[:5000].iterator():

    # Generate random email
    while True:
        random_email = get_random_string(10)
        if not User.objects.filter(email=random_email).exists():
            user.email = random_email
            break

    # Generate random username
    while True:
        random_username = get_random_string(10)
        if not User.objects.filter(username=random_username).exists():
            user.username = random_username
            break

    user.save()

1 Ответ

1 голос
/ 27 апреля 2020

IMO, ваша реализация достаточно эффективна. Теперь, если вас беспокоит слишком сильное попадание в БД, возможно, вы можете удалить filter().exists() и сгенерировать список уникальных строк заранее. Вот так:

unique_strings = list(set([get_random_string(10) for x in range(15000)]))  # or use User.objects.all().count()

for x in range(15000 - len(unique_strings)):
   # I tested with 500,000 values, did not get any duplicates so it is highly unlikely to get in this block
   new_str = get_random_string(10)
   if not new_str in unique_strings:
        unique_strings.append(new_str)

for (unique_str, user) in zip(unique_strings, User.objects.all().iterator()):
    user.username = unique_str
    user.email = unique_str
    user.save()

Тогда попадание в БД будет уменьшено с 3 до 1 раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...