Django get_or_create - 对对象列表的性能优化
考虑以下这段(伪Python)代码:
l = [some, list]
for i in l:
o, c = Model.objects.get_or_create(par1=i["something"], defaults={'par2': i["else"],})
假设大多数情况下,我们是从已有的对象中获取数据,而不是创建新的对象,
那么通过先用一个 SELECT() 查询不在 par1 定义的集合中的对象,然后再批量插入缺失的对象,显然可以提高性能。
但是,有没有简单的 Python/Django 的方法可以做到这一点,而不需要深入到 SQL 语言中呢?
这是一个批量导入的过程,所以 l 里面存的是字典,而不是 Django 模型实例。
2 个回答
1
你可以使用 Q
对象来创建一个复杂的查询,来选择已经存在的数据行。就像这样:
query_parameters = Q()
for i in l:
query_parameters |= Q(first=i['this']) & Q(second=i['that'])
found = MyModel.objects.filter(query_parameters)
然后你可以在 Python 中找出缺失的行,并用 create()
方法来创建它们(如果想提高效率,可以使用 bulk_create()
,或者如果可能会有竞争条件的话,可以用 get_or_create()
)。
当然,复杂的查询可能会有自己的性能问题,但我想这样做会比为每个项目单独查询要快。
1
如果你有一串ID,你可以用Django这个框架快速找到对应的模型实例,方法是使用__in
这个操作符。具体的用法可以参考这个链接:https://docs.djangoproject.com/en/dev/ref/models/querysets/#in
photos_exist = Photo.objects.filter(
id__in=photo_ids
)