首页 > 解决方案 > 使用随机值更新实例的有效方法

问题描述

我正在将 Django 与 PostgreSQL 一起使用,我想知道是否有办法更新一定数量的模型,这些模型具有唯一字段和随机值。

我的问题是我需要更新 5k 个用户,用随机值更改他的电子邮件和用户名。这些字段是唯一的,这意味着两个实例不能具有相同的值。我的逻辑是:对于每个用户,(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()

标签: pythondjango

解决方案


IMO,您的实施足够有效。现在,如果您担心过多地访问 DB,也许您可​​以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()

然后DB命中将从3次减少到一次。


推荐阅读