在我的应用程序中,一个“ 设置”可以与多个“ 产品”相关联。针对一组列出的产品必须定义数量。对于这种多对多关系,我遵循SQLAlchemy documentation使用带有附加列(数量)的关联表。
我正在尝试创建一个表单,用户可以在该表单中针对给定的集合分配产品和数量。集和产品都已经存在于数据库中。表单中的数据是:
这可以创建一个新的关联(例如,将集1“链接”到数量为XYZ的产品3),但是在尝试更新现有记录时出现完整性错误。
我可以按如下方式手动添加关系/记录(虚拟数据)或在Flask视图功能中添加
: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更新quantity
字段),即:
a = Set_Product_Association(set=s, product=p, quantity=43)
我收到完整性错误
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)。
奇怪的是,如果我在烧瓶视图功能中使用form.popluate_obj(set)
来处理问题here中所述的表单数据,我可以更新字段,但不能创建新的“关联”。不幸的是,我不知道那里的幕后发生了什么。...
我的模型定义如下:
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")
编辑: 我还尝试过按照建议的here反转操作:
s = Set.query.get(2)
a = Set_Product_Association()
a.quantity = 43
a.product = Product.query.get(3)
a.set = s
db.session.commit()
但是我仍然得到一个错误:
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)]
答案 0 :(得分:2)
由于尝试使用相同的主键创建新对象,因此会出现完整性错误。
此:
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()
另外,从documentation开始,建议不要使用模型,而要使用实际表。