これを行うためのより効率的な方法はありますか?
for item in item_list:
e, new = Entry.objects.get_or_create(
field1 = item.field1,
field2 = item.field2,
)
Get_or_create(またはcreate)を使用して適切な一括挿入を行うことはできず、これを簡単に行うためのAPIはありません。
テーブルが単純で、生のSQLを使用して行を作成するのがそれほど面倒ではない場合、それほど難しくはありません。何かのようなもの:
INSERT INTO site_entry (field1, field2)
(
SELECT i.field1, i.field2
FROM (VALUES %s) AS i(field1, field2)
LEFT JOIN site_entry as existing
ON (existing.field1 = i.field1 AND existing.field2 = i.field2)
WHERE existing.id IS NULL
)
ここで、%sは("field1, field2"), ("field3, field4"), ("field5, field6")
のような文字列であり、自分で適切に作成してエスケープする必要があります。
何を目指しているかによります。 manage.py
の- loaddata
関数を使用して、適切な形式(JSON、XML、YAMLなど)でデータをロードできます。
このディスカッション も参照してください。
1.4以降、bulk_createを実行できます
ドキュメント を参照してください
*ただし、注意事項に注意してください(最も重要なのは、モデルのsave()メソッドが呼び出されないため、pre_saveおよびpost_saveシグナルが送信されないことです)。*
ないでしょう。
しかし、属性としてfield1
とfield2
がある場合、item
sはどのタイプか疑問に思います。エントリを表す別のクラスが存在するようですが、models.Model
から派生していません。たぶん、このクラスを省略して、それらのアイテムを作成する代わりに、すぐにEntry
インスタンスを作成することができます。
item_list
にあるものがDBにすでに存在するかどうかわからず、モデルオブジェクトが必要な場合は、get_or_create
が間違いなく最適な方法です。
アイテムがDBにないことがわかっている場合は、次のことを行う方がはるかに良いでしょう。
for item in item_list:
new = Entry.objects.create(
field1 = item.field1,
field2 = item.field2,
)
また、オブジェクトが必要ない場合は、関数呼び出しからの戻りを無視してください。 DBの処理速度は向上しませんが、それが問題になる場合はメモリ管理に役立ちます。
データがすでにDBにあるかどうかわからないが、どちらかのフィールドにunique=True
フラグが付いている場合、DBは一意性を強制し、例外をキャッチして先に進むことができます。これにより、既存のオブジェクトを選択する試みが回避され、余分なDBヒットが防止されます。
from Django.db import IntegrityError
for item in item_list:
try:
new = Entry.objects.create(
field1 = item.field1,
field2 = item.field2,
)
except IntegrityError:
continue
どちらの場合も、トランザクションを手動で管理することで速度を上げることができます。 Djangoは、保存ごとにトランザクションを自動的に作成してコミットしますが、特定の関数で大量のDB保存を行うことがわかっている場合は、効率を大幅に向上させるデコレータを提供します。= Djangoドキュメントは、私がここでできるよりもこれらすべてを説明するのに優れていますが、おそらく特に注意を払う必要があります Django.db.transaction.commit_on_success