sqlite3.IntegrityError: UNIQUE constraint failed | When using bulk adding many-to-many relation

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')

我正在尝试使用 through-table 向产品对象批量添加类别,因为看过 or .

我用一对列表来做到这一点:product_idproductcategory_id,这也是我通过-table 包含。这会产生以下错误:

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)

我还完成了以下操作,以检查我要添加的对集中没有重复的对。有 none:

print(generic_df[generic_df.duplicated(subset=['product_object','found_categories'], keep=False)])

我怀疑错误的发生是因为某些 产品到产品类别 关系已经存在于 table 中。所以也许我应该先检查每对是否是这种情况,然后再执行 bulk_create。我只是希望保持效率,如果我必须遍历每一对来检查,我会很伤心。有没有办法针对此类问题进行批量更新或创建?

或者你怎么看?非常感谢任何帮助:-)

您可能应该检查出现这些错误的原因是否是因为重复数据。如果是这样的话,我想bulk_createignore_conflicts参数可以解决你的问题。它将保存每个有效条目并忽略那些有重复冲突的条目。

查看文档: https://docs.djangoproject.com/en/3.2/ref/models/querysets/#django.db.models.query.QuerySet.bulk_create