如何在SQLAlchemy中执行此递归公用表表达式?

时间:2012-08-16 19:25:24

标签: sql sqlalchemy

在此表架构中:

class Location(db.Model):
    id = db.Column(db.String(255), primary_key=True)
    parent_id = db.Column(db.String(255), db.ForeignKey('location.id'), nullable=True) 
    type = db.Column(db.String(255))
    name = db.Column(db.String(255))
    options = db.Column(db.Text, nullable=True)

我有一个父母,假设这个表:

> select * from location;
+--------------------------------------+--------------------------------------+---------+-----------+---------+
| id                                   | parent_id                            | type    | name      | options |
+--------------------------------------+--------------------------------------+---------+-----------+---------+
| 8821da60-e7d2-11e1-951e-ae16bc2b7368 | 88227a60-e7d2-11e1-951e-ae16bc2b7368 | city    | sengkang  | NULL    |
| 88227a60-e7d2-11e1-951e-ae16bc2b7368 | NULL                                 | country | singapore | NULL    |
+--------------------------------------+--------------------------------------+---------+-----------+---------+

父级是名为新加坡国家/地区对象。可以有更多嵌套对象,即 sengkang 的子项,就像 sengkang 新加坡的孩子一样。

所以单个层链可能看起来像 - > b - > sengkang - >新加坡

其中 - >表示

的孩子

如何获得父母为新加坡的所有位置对象,包括父对象(新加坡)? (请在SQLAlchemy中)。谢谢!

1 个答案:

答案 0 :(得分:5)

SA文档:Query.cte

我不得不说新的CTE(自0.76以来)非常好,比我不得不重做this的旧方式更好。

无论如何,认为你正在寻找这样的东西......

included_parts = session.query(Location).\
  filter(Location.name=='singapore').\
  cte(name='included_parts', recursive=True)

incl_alias = aliased(included_parts, name="pr")
parts_alias = aliased(Location, name='p')
included_parts = included_parts.union_all(
  session.query(parts_alias).filter(parts_alias.parent_id==incl_alias.c.id)
)

q = session.query(included_parts).all()