Django - SQL 批量 get_or_create 可能吗?
Posted
技术标签:
【中文标题】Django - SQL 批量 get_or_create 可能吗?【英文标题】:Django - SQL bulk get_or_create possible? 【发布时间】:2016-03-03 15:51:48 【问题描述】:我正在使用 get_or_create 将对象插入数据库,但问题是一次执行 1000 个需要很长时间。
我尝试了 bulk_create,但它没有提供我需要的功能(创建重复项、忽略唯一值、不触发我需要的 post_save 信号)。
甚至可以通过自定义的 sql 查询批量执行 get_or_create 吗?
这是我的示例代码:
related_data = json.loads(urllib2.urlopen(final_url).read())
for item in related_data:
kw = item['keyword']
e, c = KW.objects.get_or_create(KWuser=kw, author=author)
e.project.add(id)
#Add m2m to parent project
related_data 包含 1000 行,如下所示:
["cmp":0,"ams":3350000,"cpc":0.71,"keyword":"apple.",
"cmp":0.01,"ams":3350000,"cpc":1.54,"keyword":"apple -10810"......]
KW 模型还发送我用来创建另一个父模型的信号:
@receiver(post_save, sender=KW)
def grepw(sender, **kwargs):
if kwargs.get('created', False):
id = kwargs['instance'].id
kww = kwargs['instance'].KWuser
# KeyO
a, b = KeyO.objects.get_or_create(defaults='keyword': kww, keyword__iexact=kww)
KW.objects.filter(id=id).update(KWF=a.id)
这可行,但您可以想象一次处理数千行需要很长时间,甚至会导致我的小型服务器崩溃,我有哪些批量选项?
【问题讨论】:
【参考方案1】:从 Django 2.2 开始,bulk_create 有一个 ignore_conflicts
标志。每the docs:
在支持它的数据库上(除 Oracle 之外的所有数据库),将 ignore_conflicts 参数设置为 True 会告诉数据库忽略插入任何违反约束的行(例如重复唯一值)的失败
【讨论】:
【参考方案2】:如果我理解正确,“get_or_create
”表示 Postgres 端的 SELECT
或 INSERT
。
您有一个带有UNIQUE
约束或索引的表以及INSERT
(如果还没有的话)的大量行,并获取新创建的ID 或SELECT
现有行的ID。并不像表面上看起来那么简单。并发写入负载,事情就更复杂了。
还有各种参数需要定义(如何准确处理冲突):
How to use RETURNING with ON CONFLICT in PostgreSQL?【讨论】:
【参考方案3】:这篇文章可能对你有用:
***.com/questions/3395236/aggregating-saves-in-django
请注意,答案建议使用已弃用的 commit_on_success 装饰器。它被 transaction.atomic 装饰器取代。文档在这里:
transactions
from django.db import transaction
@transaction.atomic
def lot_of_saves(queryset):
for item in queryset:
modify_item(item)
item.save()
【讨论】:
以上是关于Django - SQL 批量 get_or_create 可能吗?的主要内容,如果未能解决你的问题,请参考以下文章
SQLAlchemy 是不是与 Django 的 get_or_create 等效?
SQLAlchemy 是不是与 Django 的 get_or_create 等效?
django - 使用 get_or_create 自动创建用户时设置用户权限