2017-01-27 9 views
2

Я хочу, чтобы иметь возможность выполнить следующие SQLAlchemy запросов:SQLAlchemy - Boolean Гибридный Атрибут

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

Попробуйте вызвать '.as_scalar()' на объект запроса – ThiefMaster

ответ

0

Проблема заключается в том, что total_actions и finished_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