使用@ .expression进行自联接的混合属性

时间:2016-02-26 05:34:00

标签: sqlalchemy expression self-join hybrid

在以下示例中,父表设备具有子表度量,其中包含连续天数的度量值。我通过关系 measurement_next 创建了一个自我加入,用于设置混合属性 meas_val_diff ,包含一天测量值之间的差异第二天:

class Device(Base):
    __tablename__ = 'device'

    dev_id = Column(BigInteger, Sequence('id_device_seq'), primary_key=True)

    measurements = relationship("Measurement", primaryjoin="Measurement.id_device==Device.dev_id", backref='device')


class Measurement(Base):
    __tablename__= 'measurement'
    __table_args__ = (
        UniqueConstraint('id_device', 'meas_date', name='uix_measurement_mp_meas_date'),
        Index('ix_measurement_meas_date', 'meas_date'),
        ForeignKeyConstraint(['id_device', 'meas_date'], ['measurement.id_device', 'measurement.meas_date'],
                             name='fk_measurement_mpid_ephdate', use_alter=True),
        {}
    )

    id_meas = Column(BigInteger, Sequence('measurment_seq'), primary_key=True)
    id_device = Column(BigInteger, ForeignKey('device.dev_id', name='fk_measurement_id_device'), nullable=False,)
    meas_date = Column(DateTime, nullable=False)
    meas_val = Column(Float)
    '''
    Note!! Implementation depends on the target database engine having User-Defined Function
    next_day()
    '''
    measurement_next = relationship("Measurement",
                                    primaryjoin=and_(remote(foreign(id_device)) == id_device,
                                                     remote(foreign(meas_date)) == func.next_day(meas_date)
                                                     ),
                                    remote_side=[id_device, meas_date],
                                    lazy='joined',
                                    viewonly=False,
                                    uselist=False,  # (edit)
                                    join_depth=1
                                    )

    @hybrid_property
    def meas_val_diff(self):
        return self.measurement_next.meas_val - self.meas_val

混合属性 meas_val_diff 在简单查询中正常工作。 现在我希望能够通过 meas_val_diff 进行过滤,但我不知道如何构建可实现此目的的混合表达式。 本质上,我试图得到一个类似于这样的SQL查询:

SELECT measurement.id_meas AS measurement_id_meas,
measurement.id_device AS measurement_id_device,
measurement.meas_date AS measurement_meas_date,
measurement.meas_val AS measurement_meas_val,
measurement_1.id_meas AS measurement_1_id_meas, 
measurement_1.id_device AS measurement_1_id_device,
measurement_1.meas_date AS measurement_1_meas_date, measurement_1.meas_val AS measurement_1_meas_val 
FROM measurement
LEFT OUTER JOIN measurement AS measurement_1 ON measurement_1.id_device = measurement.id_device
 AND measurement_1.meas_date = next_day(measurement.meas_date) 
WHERE (measurement_1.meas_val - measurement.meas_val) > :meas_val_1

我的粗略尝试构建一个 @ meas_val_diff.expression 方法,可以实现这样的效果:

@meas_val_diff.expression
def meas_val_diff(self):
    return self.measurement_next.meas_val - self.meas_val

结果是

属性错误("无法与InstrumentedAttribute'对象和'与Measurement.measurement_next相关联的比较器'对象具有属性' meas_val'&# 34;,)

思想?

0 个答案:

没有答案