代码之家  ›  专栏  ›  技术社区  ›  Adam Nelson

django相当于sql replace

  •  6
  • Adam Nelson  · 技术社区  · 16 年前

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

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

    假设:字段“1”或“2”上会有一个唯一的键(或者在我的例子中,两者都有),否则,这将始终计算为一个插入。

    编辑:

    我现在最好的个人回答是,但这是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')
    
    3 回复  |  直到 10 年前
        1
  •  11
  •   eternicode    14 年前

    你说你想要 REPLACE 我认为应该是 删除 插入之前的任何现有行,但您的示例指示您希望 UPSERT .

    阿法克,姜戈不支持 替换 (或SQLite的 INSERT OR REPLACE 或 上衣 )但是您的代码可以合并:

    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 或者两者都是独一无二的(如你所说)。

    这仍然是两个问题(a SELECT 对于 get_or_create 和一个 INSERT 或 UPDATE 对于 save ),但直到 上衣 -就像解决方案一样(可能不会持续很长时间),它可能是你能做的最好的。

        2
  •  9
  •   Anentropic    10 年前

    因为django 1.7你可以使用 update_or_create 方法:

    obj, created = Person.objects.update_or_create(
        first_name='John', last_name='Lennon', defaults=updated_values)
    
        3
  •  5
  •   Anentropic    10 年前

    我认为下面的内容更有效。

    (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',
          ],
       )
    

    这将仅在未创建行且需要更新时更新额外的\字段。