3

私は3つのテーブルを持っています:

class Foo(Base):
    __tablename__ = 'foo'
    id = Column(Integer, primary_key=True)
    name = Column(String(100), nullable=False)

class Bar(Base):
    __tablename__ = 'bar'
    id = Column(Integer, primary_key=True)
    name = Column(String(100), nullable=False)

class Baz(Base):
    __tablename__ = 'baz'
    id = Column(Integer, primary_key=True)
    foo_id = Column(ForeignKey('foo.id'), nullable=True)
    foo = relationship('Foo', backref='bazes')
    bar_id = Column(ForeignKey('bar.id'), nullable=True)
    bar = relationship('Bar', backref='bazes')
    name = Column(String(100), nullable=False)

したがって、Baz は Foo と Bar に戻る外部キーを持っています。

Foo に a、b、c という名前の 3 つの行があるとします。また、Bar に x、y、z という名前の 3 つの行があるとします。

答えが 0 であっても、特定の Foo と Bar の Baz の行数を取得するクエリを実行したいと思います。戻り値は次のようになります。

('a', 'x', 12)
('a', 'y', 3)
('a', 'z', 0)
('b', 'x', 9)
('b', 'y', 0)
('b', 'z', 1)
('c', 'x', 3)
('c', 'y', 6)
('c', 'z', 2)

単一の関連テーブルの場合、Baz (Baz.foo_id でグループ化) でサブクエリを実行し、Baz との外部結合を残した Foo でクエリを実行する方法を理解しています。しかし、関連する2 つのテーブルについては、途方に暮れています。このクエリを sqlalchemy で実行することは可能ですか?

4

1 に答える 1

1

私は通常、この目的のためにサブクエリを使用します。生成するSQLは次のとおりです。

SELECT foo.name, bar.name, (SELECT COUNT('*') FROM baz WHERE baz.foo_id=foo.id AND baz.bar_id=bar.id) FROM foo, bar

SQLAlchemy で:

count_query = session.query(func.count('*')).filter(Baz.foo_id==Foo.id).filter(Baz.bar_id==Bar.id).correlate(Bar).correlate(Foo).as_scalar()
query = session.query(Foo.name, Bar.name, count_query)

私は、このクエリと OUTER JOIN を巧みに組み合わせたクエリのパフォーマンスに関する専門家ではないので、これが遅くなるかどうかはわかりません。そうでなければ、次のようなことを試したでしょう:

FROM foo LEFT OUTER JOIN baz ON foo.id=baz.foo_id RIGHT OUTER JOIN bar ON bar.id=baz.bar_id

これで必要なものが得られるかどうかはわかりません。現在、サポートされていないsqliteしか利用RIGHT OUTER JOINできないため、これをテストできません。しかし、上記のクエリが希望する結果を生成することを確認しました

于 2013-10-04T12:03:25.810 に答える