2015-11-30 112 views
4

我正在使用get_or_create将对象插入数据库,但问题是一次执行1000次需要很长时间。Django - SQL批量get_or_create可能吗?

我试过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 cotains 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) 

这个工程,但你可以想象一次做成千上万的行需要很长时间,甚至崩溃我的吨iny服务器,我有什么批量选项?

回答

2

这个职位可能是你有帮助:

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() 
0

如果我理解正确的话, “get_or_create” 是指在Postgres的侧SELECTINSERT

你有一个表约束或索引UNIQUE和大量的行INSERT(如果还没有),并获得新创建的ID或否则SELECT现有行的ID。不像在外面看起来那么简单。在并发写入负载的情况下,问题更加复杂。

而且还有一些需要定义各种参数(如何处理冲突完全一致):