Python sqlalchemy hybrid_性质与表达式

Python sqlalchemy hybrid_性质与表达式,python,sqlalchemy,Python,Sqlalchemy,我听不懂这些表达。如何让下面的代码工作 class OperationType(Enum): MINUS = 1 MINUS_CORR = 2 PLUS = 3 PLUS_CORR = 4 按类型分组操作 BALANCE_PLUS_OPERATIONS = [ OperationType.PLUS.value, OperationType.PLUS_CORR.value ] BALANCE_MINUS_OPERATIONS = [ Op

我听不懂这些表达。如何让下面的代码工作

class OperationType(Enum):
    MINUS = 1
    MINUS_CORR = 2
    PLUS = 3
    PLUS_CORR = 4
按类型分组操作

BALANCE_PLUS_OPERATIONS = [
    OperationType.PLUS.value,
    OperationType.PLUS_CORR.value
]

BALANCE_MINUS_OPERATIONS = [
    OperationType.MINUS.value,
    OperationType.MINUS_CORR.value
]
运营模式

class Operation(Model):

    __tablename__ = 'operation'

    id = db.Column(db.BigInteger, primary_key=True)
    created_at = Column(db.DateTime, nullable=False, default=dt.datetime.utcnow)
    operation_type = db.Column(db.SmallInteger, nullable=False)
    amount = Column(db.Integer, nullable=False)
    user_id = db.Column(db.ForeignKey('users.id'), nullable=False)
    user = relationship('User', backref='operation', uselist=False)
用户模型

class User(UserMixin, Model):

    __tablename__ = 'users'

    id = Column(db.Integer, primary_key=True)
    operations = relationship("Operation", backref="users")

    @hybrid_property
    def balance(self):
        plus = sum(op.amount for op in self.operations if op.operation_type in BALANCE_PLUS_OPERATIONS)
        minus = sum(op.amount for op in self.operations if op.operation_type in BALANCE_MINUS_OPERATIONS)
        return plus - minus

    @balance.expression
    def balance(cls):
        p = select([func.sum(Operation.amount).label('BALANCE_PLUS_OPERATIONS')]) \
                .where(Operation.operation_type.in_(BALANCE_PLUS_OPERATIONS)) \
                .where(User.id == cls.id) \
                .as_scalar()
        m = select([func.sum(Operation.amount).label('BALANCE_MINUS_OPERATIONS')]) \
                .where(Operation.operation_type.in_(BALANCE_MINUS_OPERATIONS)) \
                    .where(User.id == cls.id) \
                    .as_scalar()
        return select([p - m]).label('BALANCE')
表达式错误,将产生错误的结果:

users = User.query.filter_by(balance=51).all()
for u in users:
    print(u, u.balance)
打印:

<User(foo@bar.com)> 51
<User(bar@foor.com)> 0
51
0
但我只希望有一张唱片:

<User(foo@bar.com)> 51
51

谢谢

我将根据上下文假设这些方法属于
用户
类。在那种情况下

.where(User.id == cls.id) \
有效地

.where(User.id == User.id) \
或者只是
where(True)
,这样每个用户都会参与到每个操作中,而这些操作可能与

.where(Operation.user_id == cls.id) \
虽然由于缺乏实例而无法说明。如果确实发生了不正确的联接,它将解释查询返回另一个用户的原因:它与属于正确用户的操作联接

您可能还需要添加

.correlate(cls) \
之前作为\u scalar()
。我认为最外层的select也是多余的。你应该能够

return (p - m).label('BALANCE')

请编辑您的问题,以解释(1)您预期会发生什么,(2)您将得到什么错误(或结果如何不同)和(3)将问题缩小到问题中的代码。阅读会有帮助的。非常感谢!我需要什么。一个站点没有提供发布所有代码的权限。基本用户和操作中有两个表。并且用户有很多操作。