Python 具有单表继承的SQLAlchemy关系
我正在对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类似于:Python 具有单表继承的SQLAlchemy关系,python,sqlalchemy,Python,Sqlalchemy,我正在对Transaction、StudentTransaction和CompanyTransaction使用SQLAlchemy的单表继承: 类TransactionBase: __tablename_uu='transaction' id=ColumnInteger,主键=True 谁付的钱?这取决于事务是否为 公司交易或学生交易。我们使用 SQLAlchemy的单表继承实现了这一点。 鉴别器=列“原点”,String50 __mapper_args_uu={'polymorphic_on'
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异常,运行脚本,它不会被调用。