6

このSQLのDjangoORMのベストプラクティスはありますか?

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

仮定:field_1またはfield_2には一意のキーがあります(または私の場合は両方にあります)。そうでない場合、これは常にINSERTに評価されます。

編集:

今の私の最高の個人的な答えはこれですが、1つが可能であるはずの2〜3のクエリです:

    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

REPLACEAFAIK、djangoは(または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(あなたが言ったように)。

それはまだ2つのクエリ(a SELECTfor get_or_create、およびINSERTor UPDATEfor save)ですが、同様のUPSERTソリューションが実現するまで(そして、長くは続かないかもしれません)、それが最善の方法である可能性があります。

于 2010-11-13T17:21:40.670 に答える
11

update_or_createDjango 1.7以降、次の方法を使用できます。

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 に答える