5

SQLAlchemy で同じテーブル データに対して 2 つのクエリを結合する正しい方法は何ですか?

つまり、次のように定義されたデータクラスがあります。

class DataMeasurement(Base):
    __tablename__ = 'DataMeasurement'
    id = Column(Integer, Sequence('data_measurement_id_seq'), primary_key=True)
    data_source = Column(String)
    timestamp = Column(DateTime)
    sensor_output = Column(Float)

...そして、一致するタイムスタンプがある次の 2 つのクエリを結合したいと思います。

q1 = self.session.query(DataMeasurement).filter_by(data_source='Sensor1').order_by(DataMeasurement.timestamp)
q2 = self.session.query(DataMeasurement).filter_by(data_source='Sensor2').order_by(DataMeasurement.timestamp)
# ...and now what?

これを簡単に行う方法はありますか?...または、根本的に欠陥のある方法でこれを行っていますか (私は SQLAlchemy の初心者です)?

4

2 に答える 2

9

サブクエリを使用します。

subq = self.session.query(DataMeasurement).\
    filter_by(data_source='Sensor1').subquery()
q = self.session.query(
    DataMeasurement.timestamp,
    # Use labels to distinguish between identically named columns.
    # This is optional.
    subq.c.sensor_output.label('output1'),
    DataMeasurement.sensor_output.label('output2')
).filter(
    (DataMeasurement.data_source == 'Sensor2') &
    (DataMeasurement.timestamp == subq.c.timestamp)
)

# Simply get a list of named tuples.
print q.all()
# Or access each column using properties.
for row in q:
    print row.timestamp, row.output1, row.output2

DataMeasurement結果をオブジェクトとして取得することもできます。

subq = self.session.query(DataMeasurement).\
    filter_by(data_source='Sensor1').subquery()
# Use alias to associate mapped class to a subquery.
dmalias = aliased(DataMeasurement, subq)
q = self.session.query(dmalias, DataMeasurement).filter(
    (DataMeasurement.data_source == 'Sensor2') &
    (DataMeasurement.timestamp == dmalias.timestamp)
)

# For each row you get a tuple containing two DataMeasurement objects.
for dm1, dm2 in q:
    print dm1.timestamp, dm1.sensor_output, dm2.sensor_output
于 2013-01-03T15:09:28.030 に答える
4

エイリアスを使用して、同じテーブル間の関係を作成できます。

あなたのクエリは次のようになります

adalias1 = aliased(DataMeasurement)
adalias2 = aliased(DataMeasurement)
q1 = self.session.query(DataMeasurement).\
        filter(
               and_(
                    adalias1.data_source in ('Sensor1', 'Sensor2'), 
                    adalias1.timestamp == adalias2.timestamp
                   )
              )
于 2013-01-03T03:54:54.500 に答える