Flask SQLAlchemy多对多关系使用额外列更新关联对象

Flask SQLAlchemy多对多关系使用额外列更新关联对象,flask,sqlalchemy,many-to-many,flask-sqlalchemy,Flask,Sqlalchemy,Many To Many,Flask Sqlalchemy,在我的应用程序中,“集合”可以有许多与之关联的“产品”。针对一组列出的产品必须定义数量。对于这种多对多关系,我遵循了使用带有附加列(数量)的关联表的步骤 我试图创建一个表单,用户可以根据给定的集合分配产品和数量。数据库中已存在集合和产品。表格中的数据包括: set.id 产品id 数量 这可以创建一个新的关联(例如,集合1“链接”到产品3,数量=XYZ),但当我尝试更新现有记录时,会出现完整性错误 我可以手动添加关系/记录(虚拟数据)或在Flask view函数中添加,如下所示: s = S

在我的应用程序中,“集合”可以有许多与之关联的“产品”。针对一组列出的产品必须定义数量。对于这种多对多关系,我遵循了使用带有附加列(数量)的关联表的步骤

我试图创建一个表单,用户可以根据给定的集合分配产品和数量。数据库中已存在集合和产品。表格中的数据包括:

  • set.id
  • 产品id
  • 数量
这可以创建一个新的关联(例如,集合1“链接”到产品3,数量=XYZ),但当我尝试更新现有记录时,会出现完整性错误

我可以手动添加关系/记录(虚拟数据)或在Flask view函数中添加,如下所示:

s = Set.query.get(2)
p = Product.query.get(3)
a = Set_Product_Association(set=s, product=p, quantity=23)
db.session.add(a)
db.session.commit()
手动更新记录(不同数量),如下所示:

s.products[0].quantity = 43
db.session.add(s)
db.session.commit()
但是,当我使用第一个块中的代码时(目的是更新给定的、现有的集合和产品ID的
数量
字段),即:

我得到一个完整性错误

sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) UNIQUE constraint failed: set_product_association.set_id, set_product_association.product_id [SQL: 'INSERT INTO set_product_association (set_id, product_id, quantity) VALUES (?, ?, ?)'] [parameters: (2, 3, 43)]
我假设这是告诉我,我试图附加一个新记录,而不是更新现有记录

我应该如何处理这个问题?“手动”方法有效,但依赖于在列表中计算出正确的索引(即正确的product.id)

奇怪的是,如果我在Flask view函数中使用
form.popluate\u obj(set)
来处理问题中描述的表单数据,我可以更新字段,但不能创建新的“关联”。不幸的是,我不知道幕后发生了什么

我的模型定义如下:

class Set_Product_Association(db.Model):
    __tablename__ = 'set_product_association'

    set_id = db.Column(db.Integer, db.ForeignKey('sets.id'), primary_key=True)
    product_id = db.Column(db.Integer, db.ForeignKey('products.id'), primary_key=True)

    quantity = db.Column(db.Integer)

    product = db.relationship("Product", back_populates="sets")
    set = db.relationship("Set", back_populates="products")

class Set(db.Model):
    __tablename__ = 'sets'

    id = db.Column(db.Integer, primary_key=True)
    products = db.relationship("Set_Product_Association", 
                                        back_populates="set")

class Product(db.Model):
    __tablename__= 'products'

    id = db.Column(db.Integer, primary_key=True)
    part_number = db.Column(db.String(100), unique=True, nullable=False)
    sets = db.relationship("Set_Product_Association", 
                                     back_populates="product")
编辑: 我还尝试按照建议逆转操作:

但我仍然得到一个错误:

sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) UNIQUE constraint failed: set_product_association.set_id, set_product_association.product_id [SQL: 'INSERT INTO set_product_association (set_id, product_id, quantity) VALUES (?, ?, ?)'] [parameters: (2, 3, 43)]

由于尝试使用相同的主键创建新对象,因此会出现完整性错误

这:

不更新,但创建

如果要更新表中的实际行,则需要更新现有行:

assoc = Set_Product_Association.query.filter_by(set=s, product=p).first()
assoc.quantity = 43
db.session.commit()

此外,从中,建议不要使用模型,而是使用实际表格。

a=Set\u Product\u Association(Set\u id=3,Product\u id=12,quantity=23)
感谢您的建议,但正如您在我引用的错误中看到的,它得到了正确的值,所以你的建议没有任何区别。非常感谢你的帮助和解释-非常感谢!工作&非常有意义。关于在模型上使用实际表,对于我的用例,如果我想遵循建议,您建议在哪里记录额外信息(数量)?保持相同的结构(集合、产品和数量),但使用
db.table
方法,而不是扩展
db.model
。可以找到一个很好的答案来解释为什么它更好,并举例说明。谢谢。很明显,我是新来的,所以如果我跟不上,很抱歉。我之所以选择模型而不是表格,是因为我需要存储有关关系的附加信息。您链接的信息指出,“总之,如果您不需要存储有关关系的额外数据,只需使用
db.Table
,它将节省您的时间。”因此,我的问题是,我确实希望存储额外的数据…保留模型,这无关紧要。
sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) UNIQUE constraint failed: set_product_association.set_id, set_product_association.product_id [SQL: 'INSERT INTO set_product_association (set_id, product_id, quantity) VALUES (?, ?, ?)'] [parameters: (2, 3, 43)]
a = Set_Product_Association(set=s, product=p, quantity=43)
assoc = Set_Product_Association.query.filter_by(set=s, product=p).first()
assoc.quantity = 43
db.session.commit()