SQLAlchemy:hybrid_property表达式和子查询

时间:2016-02-03 17:00:43

标签: python sqlalchemy

我正在尝试使用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略有不同,删除了patientFROM中的SELECT

所以我真的想知道这是不是SQLAlchemy中的错误,或者我做错了什么......非常感谢任何帮助。

0 个答案:

没有答案