以下代码可以正常运行,但是运行速度非常慢,并且如果我对太多的PostalCode对象进行尝试,则会超时。地址模型有大约一百万个对象,这些对象永远需要查询每个循环。显然,我这样做的方式是错误的,因此我们将不胜感激!这是我第一次处理大量数据。我查看并尝试了事务处理(它确实起作用,但是仍然很慢),但是我不确定这在这种情况下将如何帮助您。如果可以运行需要时间,那么当我定期执行此更新时,没有人会使用它,但是在此过程运行期间,它不能停机8个小时或类似时间。我知道我可以用芹菜来减轻负担,但是我的学习还没有那么深入,所以我真的需要首先了解这些基础知识。
楷模:
class Address(models.Model):
name = models.CharField(max_length=200, blank=True, null=True)
address = models.CharField(max_length=300, blank=True, null=True)
city = models.CharField(max_length=100, blank=True, null=True)
province = models.CharField(max_length=100, blank=True, null=True)
postal_code = models.CharField(max_length=6, blank=True, null=True)
class Meta:
indexes = [
models.Index(fields=['postal_code',]),
]
def __str__(self):
return self.address
class PostalCode(models.Model):
postal_code = models.CharField(max_length=6, blank=True, null=True)
address = models.ForeignKey('Address', on_delete=models.DO_NOTHING, blank=True, null=True)
class Meta:
indexes = [
models.Index(fields=['postal_code',]),
]
def __str__(self):
return self.postal_code
看法:
def update_postal_code_addresses(request):
postal_codes = PostalCode.objects.all()
addresses = Address.objects.all()
objs = []
for pc in postal_codes.iterator():
try:
obj = addresses.get(postal_code=pc.postal_code) # this table has about 1M rows
pc.address = obj
objs.append(pc)
except Address.DoesNotExist:
pass
PostalCode.objects.bulk_update(objs, ['address'], batch_size=100)
return redirect('home')
在Address
这里获取对象是瓶颈。您可以Adress
批量获取对象并使用字典,例如:
def update_postal_code_addresses(request):
postal_codes = PostalCode.objects.all()
addresses = Address.objects.only('pk', 'postal_code')
address_dict = {
address.postal_code: address.pk
for adress in addresses.iterator()
}
objs = []
for pc in PostalCode.iterator():
adr = address_dict.get(pc.postal_code)
if adr is not None:
pc.address_id = adr
objs.add(pc)
PostalCode.objects.bulk_update(objs, ['address'], batch_size=100)
return redirect('home')
请注意,如果有两个Address
具有相同的 postal_code
,那么我们将使用一个恰好是addresses
queryset中最新的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句