如果其他父属性与用户输入匹配,SQLAlchemy ORM 查询将返回父 ID 的子列表

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

我正在使用 SQLAlchemy 2.0 版

假设我有一个父表 - Food_Category 和一个子表 - Food_Items。一对多关系。下面是代码

class FoodCategoryModel(db.Model):
    __tablename__ = 'food_category'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    foodItems = db.relationship("FoodItemModel", back_populates="foodCategory", lazy="dynamic")


class FoodItemModel(db.Model):
    __tablename__ = 'food_item'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    foodCategoryId = db.Column(db.Integer, db.ForeignKey("food_category.id"), nullable=False)
    foodCategory = db.relationship("FoodCategoryModel", back_populates="foodItems")

然后我添加食品类别和食品项目:

db.session.add(FoodCategoryModel(id=1, name='Fruits' ))
db.session.add(FoodCategoryModel(id=2, name='Vegetables' ))
db.session.add(FoodItemModel(name='Banana', foodCategoryId=1 ))
db.session.add(FoodItemModel(name='Apple', foodCategoryId=1 ))
db.session.add(FoodItemModel(name='Orange', foodCategoryId=1 ))
db.session.add(FoodItemModel(name='Tomato', foodCategoryId=2 ))

现在,如果用户向 FoodCategoryModel 发送带有“Fruits”的查询,我希望它返回 FoodItemModel 中所有 Food Item 对象的列表。就像 - ['类对象香蕉','类对象苹果','类对象橙色']。我知道有多种方法可以实现此目的,但我正在寻找向数据库发送查询的最优雅的方法。

我试过这个,

stmt = db.select(FoodCategoryModel.foodItems).where(FoodCategoryModel.name == 'Fruits')
db.session.scalars(stmt).all()

但奇怪的是,这会返回布尔值列表 -

[True, True, True]

我希望它返回食品项目对象的列表。非常感谢社区的任何帮助和支持。

PS - 我正在使用 SQL Alchemy 2.0

python sqlalchemy orm parent-child one-to-many
1个回答
0
投票

在 SQLAlchemy 中,

relationship
函数生成一个可以执行多种操作的新属性。就您而言,它正在为每个“食品类别”创建一个动态的“食品项目”集合。因此,要访问与特定食品类别相关的食品项目,您可以使用 SQLAlchemy 自动生成的
foodItems
属性。以下是您可以做到的方法:

# First, get the required FoodCategory object
food_category = db.session.query(FoodCategoryModel).filter_by(name='Fruits').first()
# Now, you can access its related FoodItem objects
food_items = food_category.foodItems.all()

在此代码中,

food_items
将是与“Fruits”类别相关的
FoodItemModel
对象的列表。

注意,

food_category.foodItems
是一个查询对象,您可以进一步过滤、排序等。如果您只想检索所有相关对象,请使用如上所示的
all()
函数。

© www.soinside.com 2019 - 2024. All rights reserved.