【问题标题】:flask sqlalchemy many to many relationship with extra field烧瓶 sqlalchemy 与额外字段的多对多关系
【发布时间】:2016-06-18 04:02:45
【问题描述】:

我有 2 张桌子:restaurants 和 foods,以及第 3 张桌子 Restaurants_foods,它存储 2 张桌子之间的多对多关系

restaurants_foods = db.Table('restaurants_foods',
    db.Column('restaurant_id', db.Integer, db.ForeignKey('restaurants.id'), primary_key=True),
    db.Column('food_id', db.Integer, db.ForeignKey('foods.id'), primary_key=True),
    db.Column('food_price', db.Float)
)

class Food(Model):
    __tablename__ = "foods"

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)    
    name = db.Column(db.String(255), nullable=False)
    description = db.Column(db.String(255), nullable=True)


class Restaurant(Model):
    __tablename__ = "restaurants"

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)    
    name = db.Column(db.String(255), nullable=False)
    foods = db.relationship('Food', secondary=restaurants_foods)

现在当我查询 Restautant.query.get(1).foods 时,我希望它包含来自 Restaurants_foods 关联表的 food_price 列

【问题讨论】:

    标签: python flask sqlalchemy flask-sqlalchemy m2m


    【解决方案1】:

    请看一下在 SQLAlchemy 中配置many-to-many 关系。你会想要这样的东西:

    restaurants_foods = db.Table('restaurants_foods',
        db.Column('restaurant_id', db.Integer, db.ForeignKey('restaurants.id'), primary_key=True),
        db.Column('food_id', db.Integer, db.ForeignKey('foods.id'), primary_key=True),
        db.Column('food_price', db.Float))
    
    
    class Food(Model):
        __tablename__ = "foods"
    
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        name = db.Column(db.String(255), nullable=False)
        description = db.Column(db.String(255), nullable=True)
        restaurants = relationship(
            "Restaurant",
            secondary=restaurant_foods,
            back_populates="foods"
        )
    
    
    class Restaurant(Model):
        __tablename__ = "restaurants"
    
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        name = db.Column(db.String(255), nullable=False)
        foods = relationship(
            "Food",
            secondary=restaurant_foods,
            back_populates="restaurants"
        )
    

    【讨论】:

    • 我遇到了同样的问题,但我使用了Association Object 而不是db.Table。它位于@mam8cc 提供的同一链接中,仅以下一节:docs.sqlalchemy.org/en/latest/orm/…
    • “我希望它包含来自 restaurant_foods 关联表的 food_price 列”。此答案不回答问题。
    【解决方案2】:

    您必须使用association object 模式(是多对多定义的变体):当您的关联表包含除了左右表的外键之外的其他列时使用它。您无需使用 relationship.secondary 参数,而是将新类直接映射到关联表。关系左侧通过一对多引用关联对象,关联类通过多对一引用右侧。下面展示了一个映射到 Association 类的关联表,其中包括一个名为 extra_data 的列,它是一个字符串值,与 Parent 和 Child 之间的每个关联一起存储:

    class Association(Base):
        __tablename__ = 'association'
        left_id = Column(Integer, ForeignKey('left.id'), primary_key=True)
        right_id = Column(Integer, ForeignKey('right.id'), primary_key=True)
        extra_data = Column(String(50))
        child = relationship("Child", back_populates="parents")
        parent = relationship("Parent", back_populates="children")
    
    class Parent(Base):
        __tablename__ = 'left'
        id = Column(Integer, primary_key=True)
        children = relationship("Association", back_populates="parent")
    
    class Child(Base):
        __tablename__ = 'right'
        id = Column(Integer, primary_key=True)
        parents = relationship("Association", back_populates="child")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-06
      • 2020-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-02
      • 2014-09-30
      相关资源
      最近更新 更多