Я предоставлю возможные решения в Django, не прибегая к исходным данным, учитывая предоставленную вами информацию. Я обновлю этот ответ, если вы сможете предоставить больше информации, например, о базе данных, которую вы используете, и с какими ограничениями вы работаете (например, время выполнения, целостность / согласованность данных и т. Д. c.)
Решение 1
Если вы используете последнюю версию Django, вы можете использовать bulk_create
и передать ignore_conflicts=True
objects = [
Model(field_1='Object Value 1'),
Model(field_1='Object Value 2'),
Model(field_1='Object Value 3'),
Model(field_1='Object Value 1'),
]
Model.objects.bulk_create(objects, ignore_conflicts=True)
Обратите внимание на причину установки этого для параметра true:
В базах данных, которые его поддерживают (все, кроме Oracle), установка для параметра ignore_conflicts значения True указывает базе данных игнорировать сбой при вставке любых строк, которые не соответствуют ограничениям, таким как повторяющиеся уникальные значения. , Включение этого параметра отключает установку первичного ключа для каждого экземпляра модели (если база данных обычно его поддерживает).
https://docs.djangoproject.com/en/dev/ref/models/querysets/#django .db.models.query.QuerySet.bulk_create
Решение 2
В качестве альтернативы вы можете использовать django .db.transaction.atomi c для выполнения следующих действий:
- Фильтруйте объекты, уже находящиеся в db
- . Обрежьте свой список, удалив объекты, возвращенные из 1
bulk_create
тех, которые не добавлены в базу данных
objects_to_add = []
with transaction.atomic():
trimmed_list = filter_out_those_in_db(objects_to_add)
Model.objects.bulk_create(trimmed_list)
Обратите внимание, что это заблокирует базу данных во время выполнения блока кода внутри транзакции.
Атомность является определяющим свойством транзакций базы данных. Atomi c позволяет нам создать блок кода, в котором гарантируется атомарность в базе данных. Если блок кода успешно завершен, изменения фиксируются в базе данных. Если есть исключение, изменения отменяются.
https://docs.djangoproject.com/en/dev/topics/db/transactions/#django .db.transaction.atomi c
Решение 3
Если вы хотите сохранить простоту и никакие другие модели / таблицы не ссылаются на эту модель, вы можете сделать следующее:
- Фильтр для записей
- Избирательно удалите ВСЕ эти записи
- Вставьте свой список
Это очень похоже на решение 2, но вы можете выполнить шаги 1 и 2 одним движением oop в БД, сокращая время выполнения по сравнению с выполнением фильтрации в python.
Решение 4
Если вы хотите обновить существующие записи вместо того, чтобы просто не добавлять дубликаты, вы можете использовать update_or_create
для обновления существующих записей и создания не дубликатов.
Концепция похожа на get_or_create
в том смысле, что вам все равно придется делать это для каждого объекта, но часть фильтрации и обновления выполняется также в одном sw oop в БД, а не в python
Удобный метод для обновления объекта с заданными kwargs, создания нового при необходимости. По умолчанию это словарь пар (поле, значение), используемых для обновления объекта. Значения по умолчанию могут быть вызываемыми.
https://docs.djangoproject.com/en/dev/ref/models/querysets/#update -или-create