Django相当于SQL REPLACE

Ada*_*son 6 django django-orm

这个SQL是否有Django ORM最佳实践:

REPLACE app_model SET field_1 = 'some val', field_2 = 'some val';
Run Code Online (Sandbox Code Playgroud)

假设: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')
Run Code Online (Sandbox Code Playgroud)

ete*_*ode 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()
Run Code Online (Sandbox Code Playgroud)

这当然假设其中一个field_1,field_2或两个都是唯一的(如你所说).

它仍然是两个查询(SELECTfor get_or_create,and INSERTUPDATEfor save),但是直到UPSERT类似的解决方案出现(并且它可能不会持续很长时间),它可能是你能做的最好的.


Ane*_*pic 9

从Django 1.7开始你可以使用update_or_create方法:

obj, created = Person.objects.update_or_create(
    first_name='John', last_name='Lennon', defaults=updated_values)
Run Code Online (Sandbox Code Playgroud)


byo*_*ngb 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',
      ],
   )
Run Code Online (Sandbox Code Playgroud)

如果未创建行且需要更新,则仅更新extra_field.