Python 具有单表继承的SQLAlchemy关系

Python 具有单表继承的SQLAlchemy关系,python,sqlalchemy,Python,Sqlalchemy,我正在对Transaction、StudentTransaction和CompanyTransaction使用SQLAlchemy的单表继承: 类TransactionBase: __tablename_uu='transaction' id=ColumnInteger,主键=True 谁付的钱?这取决于事务是否为 公司交易或学生交易。我们使用 SQLAlchemy的单表继承实现了这一点。 鉴别器=列“原点”,String50 __mapper_args_uu={'polymorphic_on'

我正在对Transaction、StudentTransaction和CompanyTransaction使用SQLAlchemy的单表继承:

类TransactionBase: __tablename_uu='transaction' id=ColumnInteger,主键=True 谁付的钱?这取决于事务是否为 公司交易或学生交易。我们使用 SQLAlchemy的单表继承实现了这一点。 鉴别器=列“原点”,String50 __mapper_args_uu={'polymorphic_on':鉴别器} 什么时候 时间=ColumnDateTime,默认值=datetime.utcnow 是谁管理的? staff\u id=ColumnInteger,ForeignKey'staff.id' 职员=关系 "职员",, primaryjoin='and_Transaction.staff\u id==staff.id' 多少钱? 金额=列整数负表示退款,包括小数部分 交易类型 类型=列枚举 “现金”, “卡”, “转让” 类别CompanyTransactionTransaction交易: __mapper_args_uu={'polymorphic_identity':'company'} company\u id=ColumnInteger,ForeignKey'company.id' 公司=关系 “公司”, primaryjoin='and_CompanyTransaction.company_id==company.id' 类StudentTransactionTransaction: __mapper_args_uu={'polymorphic_identity':'student'} student\u id=ColumnInteger,ForeignKey'student.id' 学生=关系 “学生”, primaryjoin='and_StudentTransaction.student_id==student.id' 然后,我有一个Student,它定义了StudentTransactions的一对多关系:

班级学生人数: __tablename_uuu='student' id=ColumnInteger,主键=True 交易=关系 “学生交易”, primaryjoin='and_Student.id==StudentTransaction.Student_id', 后面是学生的 @杂化性 def balanceself: 返回金额[自我交易中交易的交易金额] 问题是,调用Student.balance函数中返回行的Student-yields:NotImplementedError:

我做错了什么

谢谢。

a是一个允许生成Python描述符的构造,该描述符在实例级别以一种方式运行,在类级别以另一种方式运行。在类级别,我们希望它生成一个SQL表达式。使用sum或list等普通Python函数来生成SQL表达式是不合法的

在本例中,如果我从student表进行查询,并且希望生成事务表中amount列的总和,那么我可能希望使用一个关联子查询和一个SQL聚合函数。我们在这里看到的SQL类似于:

SELECT * FROM student WHERE (
      SELECT SUM(amount) FROM transaction WHERE student_id=student.id) > 500
我们的混血儿必须控制并产生这种表达:

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.hybrid import hybrid_property

Base = declarative_base()

class Transaction(Base):
    __tablename__ = 'transaction'

    id = Column(Integer, primary_key=True)
    discriminator = Column('origin', String(50))
    __mapper_args__ = {'polymorphic_on': discriminator}
    amount = Column(Integer)

class StudentTransaction(Transaction):
    __mapper_args__ = {'polymorphic_identity': 'student'}

    student_id = Column(Integer, ForeignKey('student.id'))
    student = relationship(
        'Student',
        primaryjoin='and_(StudentTransaction.student_id==Student.id)'
    )

class Student(Base):
    __tablename__ = 'student'

    id = Column(Integer, primary_key=True)

    transactions = relationship(
        'StudentTransaction',
        primaryjoin='and_(Student.id==StudentTransaction.student_id)',
        back_populates='student'
    )

    @hybrid_property
    def balance(self):
        return sum([transaction.amount for transaction in self.transactions])

    @balance.expression
    def balance(cls):
        return select([
                    func.sum(StudentTransaction.amount)
                ]).where(StudentTransaction.student_id==cls.id).as_scalar()

e = create_engine("sqlite://", echo=True)
Base.metadata.create_all(e)
s = Session(e)

s.add_all([
    Student(transactions=[StudentTransaction(amount=50), StudentTransaction(amount=180)]),
    Student(transactions=[StudentTransaction(amount=600), StudentTransaction(amount=180)]),
    Student(transactions=[StudentTransaction(amount=25), StudentTransaction(amount=400)]),
])

print s.query(Student).filter(Student.balance > 400).all()
最后的输出:

SELECT student.id AS student_id 
FROM student 
WHERE (SELECT sum("transaction".amount) AS sum_1 
FROM "transaction" 
WHERE "transaction".student_id = student.id) > ?
2014-04-19 19:38:10,866 INFO sqlalchemy.engine.base.Engine (400,)
[<__main__.Student object at 0x101f2e4d0>, <__main__.Student object at 0x101f2e6d0>]

只有一个问题:balance什么时候在实例级别被调用,什么时候在类级别被调用?当我在实例级平衡上放置断点时,我仍然可以看到它正在被调用;s、 平衡。我可以在实例级别的平衡中放置一个raise异常,运行脚本,它不会被调用。