我很难理解如何在SQLAlchemy中实现递归cte。不是没有例子,就是我不懂,就是找不到。在
实际上,我在python3.7中使用django2.2,在MySQL 8中使用Conda和SQLAlchemy。但据我所知,这对我的问题并不重要。在
我根据this指南在MySQL中创建了一个相邻列表模型,并查看了SQLAlchemy的this手册。 问题在MWE之后。在
我的数据库定义是:
CREATE TABLE events (
id int(10) UNSIGNED AUTO_INCREMENT,
name varchar(255) ,
parent_id int(10) UNSIGNED DEFAULT NULL,
description varchar(255) DEFAULT=NULL,
PRIMARY KEY (id),
FOREIGN KEY (parent_id) REFERENCES events (id)
);
使用这些虚拟条目:
^{pr2}$在Django中,我创建了这个模型定义以使用SQLAlchemy进行访问
class Events(Base):
__tablename__ = 'events'
id = Column(INTEGER(10), primary_key=True)
parent_id = Column(INTEGER(10), ForeignKey('events.id'))
name = Column(String(255))
description = Column(String(255))
children = relationship('Events')
到目前为止,SQLAlchemy中的简单querys就像一个符咒。但是我不明白如何将WITH RECURSIVE
和类似的请求转换成SQLAlchemy查询。在
例如,要求5列(最后2列是通过递归更改/创建的),显示每个数据库项的树和深度:
WITH RECURSIVE hierarchy AS
(
SELECT id, name, parent_id, 1 AS depth, name AS path
FROM events
WHERE parent_id IS NULL
UNION ALL
SELECT e.id, e.name, e.parent_id, h.depth + 1, CONCAT(h.path, ' > ', e.name)
FROM hierarchy AS h
JOIN events AS e ON h.id = e.parent_id
)
SELECT * FROM hierarchy;
我找到了this查询示例,并尝试按如下方式修改它(其中as parent
应该表示上面的path
):
hierarchy = self.session.query(
Events, literal(0).label('level'), null().label('parent')
).filter(
Events.parent_id == null()
).cte(name='hierarchy',recursive=True)
h = aliased(hierarchy, 'h')
e = aliased(Events, 'e')
hierarchy = hierarchy.union(
self.session.query(
e2, (h.c.level + 1).label('level'), h.c.name
).filter(
(e2.parent_id == h.c.id)
)
)
result = self.session.query(Events, hierarchy.c.level).all()
上面代码的最后一行发出一个错误,声明(1406, "Data too long for column 'parent' at row 1")
以及创建的SQL语句:
WITH RECURSIVE hierarchy(id, parent_id, name, description, level, parent) AS (
SELECT events.id AS id, events.parent_id AS parent_id, events.name AS name, events.description AS description, %(param_1)s AS level, %(param_2)s AS parent
FROM events
WHERE events.parent_id IS NULL
UNION
SELECT e2.id AS e2_id, e2.parent_id AS e2_parent_id, e2.name AS e2_name, e2.description AS e2_description, anon_1.level + %(level_1)s AS level, anon_1.name AS anon_1_name
FROM events AS e2, hierarchy AS anon_1
WHERE e2.parent_id = anon_1.id
)
SELECT events.id AS events_id, events.parent_id AS events_parent_id, events.name AS events_name, events.description AS events_description, hierarchy.level AS hierarchy_level
FROM events, hierarchy;
问题
在SQLAlchemy查询中,.cte(recursiv=True)
到底是什么?name=hierarchy
可能正在设置一个特定的名称,否则该名称将是虚构的。
为什么会出现错误Data too long...
,我该如何解决这个问题(这个问题中的实际输出并不重要,而是要弄清楚到底什么东西太长了,它是从哪里来的)?
为什么有必要引用c
作为h
的字段,例如h.c.name
\h.c.level
,它来自哪里?
(如何在此查询中使用func.concat
来显示与CONCAT(h.path, ' > ', e.name)
相似的路径?)
我可以看出这是一个有点不寻常的问题,我可能是从一个错误的角度来看待它,但我花了相当长的时间来理解这个话题,而且还没有走得很远。在
如有任何关于如何改进我的问题的帮助或建议,我们将不胜感激。在
目前没有回答
相关问题 更多 >
编程相关推荐