Flask-SqlAlchemy允许重复的多对多关系

时间:2018-02-25 23:08:07

标签: python sqlalchemy

我有一个Order - FoodItem多对多关系,如下所示:

association_table = db.Table('association', db.Model.metadata,
    db.Column('left_id', db.Integer, db.ForeignKey('orders.order_id')),
    db.Column('right_id', db.Integer, db.ForeignKey('fooditems.fooditem_id'))
)

class OrderModel(ReviewableModel):
    __tablename__ = 'orders'
    order_id = db.Column(db.Integer, db.ForeignKey('reviewables.id'), primary_key=True)
    food_items = db.relationship("FoodItemModel", secondary = association_table)
    __mapper_args__ = {'polymorphic_identity':'orders'}

class FoodItemModel(ReviewableModel):
    __tablename__ = 'fooditems'
    fooditem_id = db.Column(db.Integer, db.ForeignKey('reviewables.id'), primary_key=True)  
    __mapper_args__ = {'polymorphic_identity':'fooditems'}

用户可以请求包含重复foodItems的订单。这是正确创建的,但是当我将更改保存到数据库时,将删除重复项。例如,我订购了3个比萨饼:

def save_to_db(self):
    print('before: '+str(self.food_items))
    db.session.add(self)
    db.session.commit()
    print('after: '+str(self.food_items))

输出如下:

before: [<FoodItemModel u'Pizza'>, <FoodItemModel u'Pizza'>, <FoodItemModel u'Pizza'>]
after: [<FoodItemModel u'Pizza'>]

关联表格正确更新:

"left_id"   "right_id"
"6"         "3"
"6"         "3"
"6"         "3"

但是,OrderModel中的food_items只包含1个项目

1 个答案:

答案 0 :(得分:3)

您必须为关联表声明主键。

Flask-SQLALchemy是一个ORM,它需要一系列唯一标识行的列。

看看这部分文档,有点过时,但仍然有效: http://docs.sqlalchemy.org/en/rel_1_1/faq/ormconfiguration.html#faq-mapper-primary-key

Flask-SQLALchemy使用所有字段(left_id,right_id)来标识行,并且所有行都具有相同的值(6,3)。因此,所有行都存储在数据库中(因为它没有任何声明的约束),但只有一行保留在上下文(内存)中。