Sqlite3.IntegrityError: UNIQUE constraint failed | When using bulk adding many-to-many relation
У меня есть две модели, где одна из них имеет поле TreeManyToMany (поле "многие ко многим" для django-mptt моделей).
class ProductCategory(models.Model):
pass
class Product(models.Model):
categories = TreeManyToManyField('ProductCategory')
Я пытаюсь добавить категории к объектам Product массово с помощью сквозной таблицы, как показано в этой теме или в этой.
Я делаю это с помощью списка пар: product_id и productcategory_id, который также содержит моя сквозная таблица. Это приводит к следующей ошибке:
sqlite3.IntegrityError: UNIQUE constraint failed: products_product_categories.product_id, products_product_categories.productcategory_id
Мой код выглядит следующим образом:
def bulk_add_cats(generic_df):
# A pandas dataframe where ["product_object"] is the product_id
# and ["found_categories"] is the productcategory_id to add to that product.
generic_df = generic_df.explode("found_categories")
generic_df["product_object"] = generic_df.apply(
lambda x: Product.objects.filter(
merchant = x["forhandler"], product_id = x["produktid"]
).values('id')[0]['id'], axis=1
)
# The actual code
# Here row.product_object is the product_id and row.found_categories is one
# particular productcategory_id, so they make up a pair to add to the through-table.
through_objs = [
Product.categories.through(
product_id = row.product_object,
productcategory_id = row.found_categories
) for row in generic_df.itertuples()
]
Product.categories.through.objects.bulk_create(through_objs, batch_size=1000)
Я также сделал следующее, чтобы проверить, нет ли дублирующих пар в наборе пар, которые я хочу добавить. Их не было:
print(generic_df[generic_df.duplicated(subset=['product_object','found_categories'], keep=False)])
Я подозреваю, что ошибка возникает потому, что некоторые из отношений product-to-productcategory уже существуют в таблице. Так что, возможно, мне следует сначала проверить, так ли это, для каждой пары, а затем выполнить bulk_create. Я просто хочу надеяться на сохранение эффективности и буду огорчен, если мне придется итерировать каждую пару для проверки. Есть ли способ bulk-update-or-create для такого типа проблем?
Или что вы думаете? Любая помощь будет высоко оценена :-)
Вы, вероятно, должны проверить, не является ли причиной возникновения этих ошибок дублирование данных. Если это так, то я думаю, что параметр ignore_conflicts в bulk_create может решить вашу проблему. Он будет сохранять каждую действительную запись и игнорировать те, которые имеют дублирующий конфликт.
Проверьте документ: https://docs.djangoproject.com/en/3.2/ref/models/querysets/#django.db.models.query.QuerySet.bulk_create