非常に大きなデータセットのMySQLデータベースに一括挿入しようとしていますが、重複エラーを無視してDjangoのbulk_create
を使用したいと考えています。
サンプルモデル:
class MyModel(models.Model):
my_id=models.IntegerField(primary_key=True)
start_time = models.DateTimeField()
duration = models.IntegerField()
......
description = models.CharField(max_length=250)
これまでのところ、次のコードがあります(すべてのモデルに一般的で、Model_instance()と[bulk_createオブジェクトのリスト]を渡します)。
def insert_many(model, my_objects):
# list of ids where pk is unique
in_db_ids = model.__class__.objects.values_list(model.__class__._meta.pk.name)
if not in_db_ids:
# nothing exists, save time and bulk_create
model.__class__.objects.bulk_create(my_objects)
else:
in_db_ids_list = [elem[0] for elem in in_db_ids]
to_insert=[]
for elem in my_objects:
if not elem.pk in in_db_ids_list:
to_insert.append(elem)
if to_insert:
model.__class__.objects.bulk_create(to_insert)
Django重複を避けるためにこれを行う方法はありますか?MySQLのinsert ignore
を模倣するのは素晴らしいことです。単にbulk_create
(非常に高速)を使用する場合、私は主キーが重複していて挿入が停止すると、エラーが発生します。
この関数はそれを行います。
注:これは、一意のpk
があり、他にunique
がない場合にのみ機能します。
_def insert_many(model, my_objects):
# list of ids where pk is unique
in_db_ids = model.__class__.objects.values_list(model.__class__._meta.pk.name)
if not in_db_ids:
# nothing exists, save time and bulk_create
model.__class__.objects.bulk_create(my_objects)
else:
in_db_ids_list = [elem[0] for elem in in_db_ids]
to_insert = []
for elem in my_objects:
if elem.pk not in in_db_ids_list and elem.pk not in to_insert:
to_insert.append(elem)
if to_insert:
model.__class__.objects.bulk_create(to_insert)
_
使い方insert_many(MyModel(), list_of_myModels_defined_but_not_saved)
ignore_conflictsパラメーターがbulk_create( Django 2.2 )
また、 https://github.com/Django/django/search?q=ignore_conflicts&unscoped_q=ignore_conflicts でも見つけることができます。