我有三张桌子:
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。
Say Foo有三行,名称为a,b和c。并且说Bar有三行,名称为x,y和z。
我想执行一个查询来获取给定Foo和Bar的Baz中的行数,即使答案为0.对于返回值,这样的事情是这样的:
('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分组),然后查询Foo,使用Baz留下外连接。但是对于两个相关的表,我很茫然。是否可以在sqlalchemy中执行此查询?
答案 0 :(得分: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
所以我无法测试这个。但我已经验证了上述查询生成了您想要的结果。