存在しない場合は作成


81

Web APIからデータを読み取り、それをデータベースに配置するDjangoアプリケーションがあります。
モードから新しいオブジェクトを作成するが、オブジェクトがすでに存在する場合に重複例外を防ぐ方法はありますか?

言い換えれば、オブジェクトを保存する方法はありますが、オブジェクトがすでに存在する場合は何もしませんか?

回答:


161

9
ドキュメントへのリンクにすることで、いくつかの文字が追加されます(そして、私が推測するより良い答えになります)
2

4
これは2つのクエリを行うようです。オブジェクトが存在しない場合にのみオブジェクトを保存したい場合、クエリを1つだけにする方法はありますか?キャッチするIntegrityErrorと現在のトランザクションが中止され、十分ではないと思います。
Amir Ali Akbari 2015年

あなたが使用してセーブポイント、例えばを追加する場合は、整合性エラーをキャッチすることができますtransaction.atomicあなたがキャッチします(atomicすなわち、ブロックをtry: with acomic: create; except IntegrityErrorそれはあなたがキャッチしていないことを確認することも難しいです。他のあなたがするつもりのものより整合性エラー

をキャッチできればIntegrityError、私のテストでは、レコードが存在する場合、と比較して実行時間がほぼ半分に短縮されることが示されていget_or_create()ます。
ロン


3

Djangoの新しいバージョンでは、save()関数がデフォルトでUPDATEまたはINSERTを実行するように見えます。こちらをご覧ください


自動的に適切に選択されるように見えますが、現在、私のデータベースでは、スクリプトを実行してデータベースにデータを入力するたびにエントリが複製されています。
martin-martin 2018

save()メソッドは、モデルのPKに値があるかどうかを確認します。この手法を使用するには、作成者は正しいPKを持つモデルインスタンスを取得するためにDBにクエリを実行する必要があります。save()を単独で使用しても、魔法は実行されません。
chickahoona

0

それは使用して達成することができます Model.objects.get_or_create()


obj, created = Person.objects.get_or_create(
    first_name='John',
    last_name='Lennon',
    defaults={'birthday': date(1940, 10, 9)},
)

任意のキーワード引数(ここではFIRST_NAMELAST_NAME get_or_create()に渡された) -と呼ばれるオプションの1を除きますデフォルトは-データベース内(オブジェクトを見つける)、データベースのクエリに使用されます。

タプルを返します。オブジェクトが見つかった場合、get_or_create()はそのオブジェクトのタプルを返し、Falseを返します。

try exceptステートメントを使用して同じことを実現することもできます
例:

try:
    obj = Person.objects.get(first_name='John', last_name='Lennon')
except Person.DoesNotExist:
    obj = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))
    obj.save()
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.