我正在尝试使用SQLAlchemy执行复杂的hybrid_property:我的模型是
class Consultation(Table):
patient_id = Column(Integer)
patient = relationship('Patient', backref=backref('consultations', lazy='dynamic'))
class Exam(Table):
consultation_id = Column(Integer)
consultation = relationship('Consultation', backref=backref('exams', lazy='dynamic'))
class VitalSign(Table):
exam_id = Column(Integer)
exam = relationship('Exam', backref=backref('vital', lazy='dynamic'))
vital_type = Column(String)
value = Column(String)
class Patient(Table):
patient_data = Column(String)
@hybrid_property
def last_consultation_validity(self):
last_consultation = self.consultations.order_by(Consultation.created_at.desc()).first()
if last_consultation:
last_consultation_conclusions = last_consultation.exams.filter_by(exam_type='conclusions').first()
if last_consultation_conclusions:
last_consultation_validity = last_consultation_conclusions.vital_signs.filter_by(sign_type='validity_date').first()
if last_consultation_validity:
return last_consultation_validity
return None
@last_consultation_validity.expression
def last_consultation_validity(cls):
subquery = select([Consultation.id.label('last_consultation_id')]).\
where(Consultation.patient_id == cls.id).\
order_by(Consultation.created_at.desc()).limit(1)
j = join(VitalSign, Exam).join(Consultation)
return select([VitalSign.value]).select_from(j).select_from(subquery).\
where(and_(Consultation.id == subquery.c.last_consultation_id, VitalSign.sign_type == 'validity_date'))
正如您所看到的,我的模型非常复杂。 患者得到咨询。考试和VitalSigns是协商的级联数据。这个想法是所有的协商都没有得到有效性,但是新的协商使得先前的协商有效性没有意义:我只想要上次咨询的有效性;如果患者在之前的咨询中有效,我不感兴趣。
我想做的是能够通过hybrid_property last_consultation_validity进行排序。
输出SQL对我来说没问题:
SELECT vital_sign.value
FROM (SELECT consultation.id AS last_consultation_id
FROM consultation, patient
WHERE consultation.patient_id = patient.id ORDER BY consultation.created_at DESC
LIMIT ? OFFSET ?), vital_sign JOIN exam ON exam.id = vital_sign.exam_id JOIN consultation ON consultation.id = exam.consultation_id
WHERE consultation.id = last_consultation_id AND vital_sign.sign_type = ?
但是当我通过last_consultation_validity订购患者时,行没有被订购......
当我在hybrid_property之外执行相同的select时,为每个患者检索日期(只是设置patient.id),我得到了好的值。令人惊讶的是,SQL略有不同,删除了patient
中FROM
中的SELECT
。
所以我真的想知道这是不是SQLAlchemy中的错误,或者我做错了什么......非常感谢任何帮助。