SQLAlchemy - 布尔混合属性

时间:2017-01-27 05:12:52

标签: python flask sqlalchemy flask-sqlalchemy

我希望能够运行以下SQLAlchemy查询:

q_done = Batch.query.filter(Batch.done)
q_running = Batch.query.filter(~Batch.done)

但我无法围绕撰写与expression混合属性相对应的done

SQLAlchemy模型:

class Action(db.Model):
    id          = db.Column(db.Integer, primary_key=True)
    action      = db.Column(db.String(32))
    done        = db.Column(db.Boolean, default=False)
    batch       = db.relationship(Batch.__name__, backref='actions')

class Batch(db.Model):
    id                = db.Column(db.Integer, primary_key=True)
    name              = db.Column(db.String(255), default='unknown')

    @hybrid_property
    def total_actions(self):
        return db.session.query(Action).join(Action.batch).filter(Batch.id == self.id).count()

    @hybrid_property
    def finished_actions(self):
        return db.session.query(Action).join(Action.batch).filter(Batch.id == self.id).filter(Action.done).count()

    @hybrid_property
    def done(self):
        return self.total_actions == self.finished_actions

我试图实现相应的expression但没有取得多大成功。我很难理解如何返回一个布尔查询。这是我谦虚的尝试:

@done.expression
def done(self):
    total_actions = db.session.query(func.sum(Batch.actions))
    finished_actions = db.session.query(func.sum(Batch.actions.done))
    return db.session.query(Batch).filter(total_actions == finished_actions)

1 个答案:

答案 0 :(得分:0)

问题是total_actionsfinished_actions都是hybrid attributes,因此无法在expression done中使用。

我必须为每个返回查询而不是值的expression添加相应的class Action(db.Model): id = db.Column(db.Integer, primary_key=True) action = db.Column(db.String(32)) done = db.Column(db.Boolean, default=False) batch = db.relationship(Batch.__name__, backref='actions') class Batch(db.Model): id = db.Column(db.Integer, primary_key=True) @hybrid_property def total_actions(self): return db.session.query(Action).join(Action.batch).filter(Batch.id == self.id).count() @total_actions.expression def total_actions(cls): return (select([func.count(Action.id)]). where(Action.bid == cls.id). label("total_actions")) @hybrid_property def finished_actions(self): return db.session.query(Action).join(Action.batch).filter(Batch.id == self.id).filter(Action.done).count() @finished_actions.expression def finished_actions(cls): return (select([func.count(Action.id)]). where(Action.bid == cls.id). where(Action.done). label("finished_actions")) @hybrid_property def done(self): return self.total_actions == self.finished_actions @done.expression def done(cls): return cls.total_actions == cls.finished_actions

以下是完整的代码:

Games