flask sqlalchemy 与额外字段的多对多关系

问题描述 投票:0回答:2

我有 2 个表:餐厅和食品,以及第三个表restaurants_foods,它存储两个表之间的多对多关系

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
2个回答
20
投票

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

class Parent(Base):
    __tablename__ = "left_table"
    id: Mapped[int] = mapped_column(primary_key=True)

    children: Mapped[List["Association"]] = relationship(back_populates="parent")


class Association(Base):
    __tablename__ = "association_table"
    left_id: Mapped[int] = mapped_column(ForeignKey("left_table.id"), primary_key=True)
    right_id: Mapped[int] = mapped_column(
        ForeignKey("right_table.id"), primary_key=True
    )
    extra_data: Mapped[Optional[str]]

    child: Mapped["Child"] = relationship(back_populates="parents")
    parent: Mapped["Parent"] = relationship(back_populates="children")


class Child(Base):
    __tablename__ = "right_table"
    id: Mapped[int] = mapped_column(primary_key=True)

    parents: Mapped[List["Association"]] = relationship(back_populates="child")

0
投票

请查看在 SQLAlchemy 中配置多对多关系。 你会想要这样的东西:

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"
    )
© www.soinside.com 2019 - 2024. All rights reserved.