Flask 通过关联表选择项目

Flask 通过关联表选择项目,flask,sqlalchemy,Flask,Sqlalchemy,我正在建立一个食谱数据库。我试图构建一个查询,在这里我得到了所有包含特定成分(如洋葱、胡萝卜)的答案,但我不知道如何构建我的查询。基本上,我正在尝试得到一个含有成分的配方列表(给定适当的加入量)。名称='洋葱'。我的模型如下: ingredients = db.Table('ingredients', db.Column('modified_ingredient', db.Integer, db.ForeignKey('modified_ingredient.id')), db.

我正在建立一个食谱数据库。我试图构建一个查询,在这里我得到了所有包含特定成分(如洋葱、胡萝卜)的答案,但我不知道如何构建我的查询。基本上,我正在尝试得到一个含有成分的配方列表(给定适当的加入量)。名称='洋葱'。我的模型如下:

ingredients = db.Table('ingredients',
    db.Column('modified_ingredient', db.Integer, db.ForeignKey('modified_ingredient.id')),
    db.Column('ingredient', db.Integer, db.ForeignKey('ingredient.id'))
    )

modifiers = db.Table('modifiers',
    db.Column('modified_ingredient', db.Integer, db.ForeignKey('modified_ingredient.id')),
    db.Column('modifier', db.Integer, db.ForeignKey('modifier.id'))
    )

modified_ingredients = db.Table('modified_ingredients',
    db.Column('recipe', db.Integer, db.ForeignKey('recipe.id')),
    db.Column('modified_ingredient', db.Integer, db.ForeignKey('modified_ingredient.id'))
    )

class Recipe(db.Model):
    __tablename__ = 'recipe'

    id = db.Column(db.Integer, primary_key=True)

    name = db.Column(db.String(256))
    description = db.Column(db.Text)
    directions = db.Column(db.Text)
    prep_time = db.Column(db.Integer)
    cook_time = db.Column(db.Integer)
    image = db.Column(db.LargeBinary())
    ingredients = db.relationship('ModifiedIngredient', secondary=modified_ingredients)

class Ingredient(db.Model):
    __tablename__ = 'ingredient'

    id = db.Column(db.Integer, primary_key=True)

    name = db.Column(db.String(30), index=True, unique=True)

class Modifier(db.Model):
    __tablename__ = 'modifier'

    id = db.Column(db.Integer, primary_key=True)

    name = db.Column(db.String(30), index=True, unique=True)

class ModifiedIngredient(db.Model):
    __tablename__ = 'modified_ingredient'

    id = db.Column(db.Integer, primary_key=True)

    amount = db.Column(db.Integer)
    unit = db.Column(db.String(20))
    ingredients = db.relationship('Ingredient', secondary=ingredients, 
        backref=db.backref('ingredients', lazy='dynamic'), lazy='dynamic')
    modifiers = db.relationship('Modifier', secondary=modifiers,
        backref=db.backref('modifiers', lazy='dynamic'), lazy='dynamic')

困扰我的主要是我对SQL和SQLAlchemy的缺乏经验。我知道我加入了一些东西,但我不确定如何用一种有效的方式来表达它。

选项1:非常整洁,但可能不是最有效的,因为嵌套的
EXISTS
子句:

q = (db.session.query(Recipe)
     .filter(Recipe.ingredients.any(
         ModifiedIngredient.ingredients.any(
             Ingredient.name == 'onion')
     )))
选项2:应该更快,但是如果您只查询某些列(使用
查询(Recipe.name,…)
而不是下面的整个对象),您将以每个
配方
行的多个结果结束,因为
连接

q = (db.session.query(Recipe)
     .join(Recipe.ingredients)
     .join(Ingredient, ModifiedIngredient.ingredients)
     .filter(Ingredient.name == 'onion')
     )

有点离题——但感觉你的模特有点离题。目前,它是“一个配方有许多改良成分,每个改良成分由许多成分和许多改良剂组成”。所以我认为
修饰成分
应该是与
成分和
修饰成分的一对多关系,而不是现在的多对多关系?这将使关系“一个配方有许多修改成分,每个修改成分由一个修改成分和一种成分组成”。好吧,一种成分可以有多个修改(例如炖番茄和切成丁的番茄)听起来像是你想要设置所有可能的项目,所以你可以说“让我看看所有的番茄”,它会显示你是罐装的,切成丁、压碎、整粒等,但不脱咖啡因。但是
配方
修改成分
之间的关系意味着您无法真正做到这一点。“西红柿汤”配方:它需要
改良成分(数量=2,单位=Can',成分=[成分(名称='罐装西红柿')],改良剂=[改良剂('压碎])
这不能转移到只需要一个切成丁的罐头的“博洛尼亚”配方——它需要一个新的
改良成分
条目,多个修饰符都不起作用,我实际上选择了选项二,在你发布这篇文章之前我已经想好了。如果.filter(component.name=='onion',component.name=='tomato')似乎不起作用,我如何使用它来获取多个成分如果您需要
条件,您可以添加另一个过滤器:
.filter(component.name=='tomato')
。如果您需要
,则
过滤器(或(component.name=='洋葱',component.name=='番茄'))
即可。