Django bulk создать игнорировать дубликаты
Я пытаюсь вставить объем в MySQL db для очень большого набора данных и хотел бы использовать 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
(очень быстро), я получаю сообщение об ошибке, если есть дубликат первичного ключа и остановка вставки.
Ответы
Ответ 1
Эта функция сделает это.
Примечание: это будет работать, только если у вас есть уникальный 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)
Ответ 2
Параметр ignore_conflicts был добавлен в bulk_create (Django 2.2)
и вы также можете найти его в https://github.com/django/django/search?q=ignore_conflicts&unscoped_q=ignore_conflicts