6

此 SQL 是否有 Django ORM 最佳实践:

REPLACE app_model SET field_1 = 'some val', field_2 = 'some val';

假设:field_1 或 field_2 将有一个唯一的键(或在我的情况下两者都有),否则这将始终评估为 INSERT。

编辑:

我现在最好的个人答案是这个,但它是 2-3 个查询,其中 1 应该是可能的:

    from django.core.exceptions import ValidationError
    try:
        Model(field_1='some val',field_2='some val').validate_unique()
        Model(field_1='some val',field_2='some val',extra_field='some val').save()
    except ValidationError:
        Model.objects.filter(field_1='some val',field_2='some val').update(extra_field='some val')
4

3 回答 3

11

你说你想要REPLACE,我认为应该在插入之前删除任何现有的行,但你的例子表明你想要更像UPSERT.

AFAIK,django 不支持REPLACE(或 sqlite 的INSERT OR REPLACE,或UPSERT)。但是您的代码可以合并:

obj, created = Model.objects.get_or_create(field_1='some val', field_2='some_val')
obj.extra_field = 'some_val'
obj.save()

这当然假设field_1,field_2或两者都是唯一的(如您所说)。

它仍然是两个查询(一个SELECTforget_or_create和一个INSERTor UPDATEfor save),但直到出现UPSERT类似的解决方案(并且可能不会持续很长时间),它可能是您能做的最好的。

于 2010-11-13T17:21:40.670 回答
11

从 Django 1.7 开始,您可以使用update_or_create以下方法:

obj, created = Person.objects.update_or_create(
    first_name='John',
    last_name='Lennon',
    defaults={'profession': 'musician'},
)
于 2016-01-27T17:13:33.200 回答
5

我认为以下更有效。

(obj, created) = Model.objects.get_or_create(
   field_1 = 'some val',
   field_2 = 'some_val',
   defaults = {
      'extra_field': 'some_val'
   },
)
if not created and obj.extra_field != 'some_val':
   obj.extra_field = 'some_val'
   obj.save(
      update_fields = [
         'extra_field',
      ],
   )

如果行没有创建并且需要更新,这只会更新 extra_field。

于 2014-12-12T15:07:35.247 回答