排除已连接表

时间:2018-01-11 22:02:06

标签: python sqlalchemy

我想获取foo

中没有引用的表bar的实例(行)

foo

+----+-----+
| id | baz |
+----+-----+
|  1 |  23 |
|  2 |  56 |
|  3 |  45 |
|  4 |  78 |
+----+-----+

bar

+-----+--------+-----+
| id  | foo_id | zab |
+-----+--------+-----+
|  7  |      2 | s1  |
|  8  |      4 | s2  |
+-----+--------+-----+

我的查询结果应该是foo的实例,如下所示:

+----+-----+
| id | baz |
+----+-----+
|  1 |  23 |
|  3 |  45 |
+----+-----+

使用SQLAlchemy ORM,我尝试了joinouterjoin,但解决方案仍在逃避。有些东西告诉我,解决方案很简单,就在我面前......

q = db.session.query(Foo).join(Baz, Baz.foo_id == Foo.id)

q = db.session.query(Foo).outerjoin(Baz, Baz.foo_id == Foo.id)

1 个答案:

答案 0 :(得分:4)

您正在寻找的SQL查询是:

SELECT foo.* FROM foo LEFT JOIN bar ON bar.foo_id = foo.id WHERE bar.foo_id IS NULL;
LEFT JOIN相对,

INNER JOIN包含来自'左边'的所有行。表格(即FROM tblname中指定的表格),即使它们在'右边没有关联的行? table(JOIN tblname中指定的表)。这意味着右表中没有关联行的行将改为NULL值:

foo.id | foo.baz | bar.id | bar.foo_id | bar.zab
-------+---------+--------+------------+--------
     1 |      23 |   NULL |       NULL |    NULL
     2 |      56 |      7 |          2 |      s1

因此,过滤那些在右表的主键中具有NULL的行(在任何其他情况下都不能为空,而右表中的其他列可能是),您获得没有关联foo的{​​{1}}行。

在SQLAlchemy中,它变为:

bar

使用SQLAlchemy,q = db.session.query(Foo).join(Bar, isouter=True).filter(Bar.id == None) 的{​​{1}}标记为how you do a LEFT JOIN