【问题标题】:Django - SQL bulk get_or_create possible?Django - SQL 批量 get_or_create 可能吗?
【发布时间】: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)

这可行,但您可以想象一次处理数千行需要很长时间,甚至会导致我的小型服务器崩溃,我有哪些批量选项?

【问题讨论】:

    标签: sql django postgresql django-models


    【解决方案1】:

    从 Django 2.2 开始,bulk_create 有一个 ignore_conflicts 标志。每the docs

    在支持它的数据库上(除 Oracle 之外的所有数据库),将 ignore_conflicts 参数设置为 True 会告诉数据库忽略插入任何违反约束的行(例如重复唯一值)的失败

    【讨论】:

      【解决方案2】:

      如果我理解正确,“get_or_create”表示 Postgres 端的 SELECTINSERT

      您有一个带有UNIQUE 约束或索引的表以及INSERT(如果还没有的话)的大量行,并获取新创建的ID 或SELECT 现有行的ID。并不像表面上看起来那么简单。并发写入负载,事情就更复杂了。

      还有各种参数需要定义(如何准确处理冲突):

      【讨论】:

        【解决方案3】:

        这篇文章可能对你有用:

        stackoverflow.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()
        

        【讨论】:

          猜你喜欢
          • 2011-01-16
          • 2021-09-15
          • 2014-09-21
          • 1970-01-01
          • 2015-06-09
          • 1970-01-01
          • 2017-11-05
          • 2018-05-12
          • 1970-01-01
          相关资源
          最近更新 更多