我正在使用Flask-SQLAlchemy开展一个项目。
模型如下所示: 汽车有组件, 组件可能有问题
car有一个column_property'inscess_repair',当汽车的组件出现问题时,这是真的
needs_repair = column_property(exists().where(and_(
carcomponent.columns['car_id'] == id,
carcomponent.columns['component_id'] == componentissue.columns['component_id']
)))
我为带有'skip'-column的标签添加了一个表,通过表iss_car_tag分配标签(忽略组件,仅引用特定的汽车发行关系)。
现在,如果所有已分配的标签都跳过了False或没有分配标签,我希望needs_repair为真
如何扩展column_property以实现此目的?
编辑: 型号/表定义:
class Component(Base):
id = db.Column(db.Integer, primary_key=True)
[...]
issues = db.relationship('ISsue', secondary=componentissue, lazy='dynamic',
back_populates='components')
cars = db.relationship('Car', lazy = 'dynamic', secondary=carcomponent,
back_populates="component"
broken = column_property(exists().where(componentissue.columns['component_id'] == id))
class Car(Base):
id = db.Column(db.Integer, primary_key=True)
[...]
components = db.relationship('Component', secondary=carcomponent,
back_populates="cars", lazy='dynamic')
needs_repair = column_property(exists().where(and_(
carcomponent.columns['car_id'] == id,
carcomponent.columns['component_id'] == componentissue.columns['component_id']
)))
class Issue(Base):
__tablename__ = "issues"
[...]
components = db.relationship('Component' lazy = 'dynamic', secondary=componentissue,
back_populates='issues')
class Tag(Base):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Text, unique=True)
description = db.Column(db.Text, nullable=False, default="")
skip = db.Column(db.Boolean, default = False)
class Issue_Car_Tag(Base):
id = db.Column(db.Integer, primary_key=True)
tag_id = db.Column(db.Integer, db.ForeignKey('tag.id'))
car_id = db.Column(db.Integer, db.ForeignKey('car.id'))
issue_id = db.Column(db.Integer, db.ForeignKey('issue.id'))
tag = db.relationship('Tag', backref=db.backref('issue_car_tags'))
car = db.relationship('Car', backref=db.backref('issue_car_tags'))
issue = db.relationship('Issue', backref=db.backref('issue_car_tags'))
答案 0 :(得分:1)
如果您在Tag和Issue_Car_Tag的定义之后移动Car的定义或以其他方式引用这些表,则可以生成以下查询构造
func.coalesce(func.bool_and(not_(Tag.skip)), False).\
select().\
where(Tag.id == Issue_Car_Tag.tag_id).\
where(Issue_Car_Tag.car_id == id).\
as_scalar()
并在现有支票的OR中使用它:
needs_repair = column_property(
or_(func.coalesce(func.bool_and(not_(Tag.skip)), False).
select().
where(Tag.id == Issue_Car_Tag.tag_id).
where(Issue_Car_Tag.car_id == id).
as_scalar(),
exists().where(and_(
carcomponent.c.car_id == id,
carcomponent.c.component_id == componentissue.c.component_id))))
查询使用关联表issue_car_tag和aggregates跳过值,coalescing空结果或所有空值选择与汽车相关的标签。
请注意,如果未分配任何标记,则会导致false,因此您必须单独处理。如果我已正确理解您的现有查询,则这已由您的EXISTS表达式处理。换句话说,如果标签存在并且所有标签都跳过设置为false,则新查询结果为true。