web-dev-qa-db-ja.com

django一括作成は重複を無視します

非常に大きなデータセットの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(非常に高速)を使用する場合、私は主キーが重複していて挿入が停止すると、エラーが発生します。

20
tr33hous

この関数はそれを行います。
注:これは、一意の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)

6
Will Farley

ignore_conflictsパラメーターがbulk_createDjango 2.2

また、 https://github.com/Django/django/search?q=ignore_conflicts&unscoped_q=ignore_conflicts でも見つけることができます。

6
gaozhidf