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=='番茄'))
即可。