【发布时间】:2021-10-22 05:38:55
【问题描述】:
我有一个包含分层数据的表,其中每一行包含一个 id、parent_id、level(深度)以及一个路径枚举 hierarchy_hint,它是一个具有类似 JSON 格式的纯字符串。例如:
| id | parent_id | level | hierarchy_hint |
|---|---|---|---|
| 1 | null | 'level1' | '{"level1": "root"}' |
| 2 | 1 | 'level2' | '{"level1": "root", "level2: "shoes"}' |
| 3 | 2 | 'level3' | '{"level1": "root", "level2: "shoes", "level3": "athletic"}' |
(例如,我使用整数,但 id 是 UUID)
我想使用hierarchy_hint 在特定level 处获取给定Node 的所有后代。该模型已经建立了自引用关系以获取直系后代 (children)。模型如下:
class Node(db.Model):
id = db.Column(UUID(as_uuid=True), primary_key=True)
parent_id = db.Column(UUID(as_uuid=True), db.ForeignKey('node.id'))
children = db.relationship('Node')
level = db.Column(db.String(length=4000), primary_key=False)
hierarchy_hint = db.Column(db.String(length=200), primary_key=False)
我已经尝试添加到模型中:
level_threes = relationship(
"Node", primaryjoin=and_(
foreign(hierarchy_hint).like(func.regexp_replace(hierarchy_hint, '}', ',%%')),
level == 'level3'), viewonly=True)
但我得到了错误:
sqlalchemy.exc.ArgumentError: Relationship Node.level_threes could not determine any unambiguous local/remote column pairs based on join condition and remote_side arguments. Consider using the remote() annotation to accurately mark those elements of the join condition that are on the remote side of the relationship.
我怀疑因为我正在使用regexp_replace 修改hierarchy_hint,所以我应该以某种方式使用secondary 表,但我对SQLAlchemy 的经验不足,不知道该怎么做。
我也愿意接受有关如何使用递归查询或其他方式执行此操作的替代建议,但我希望能够以与访问 children 相同的方式访问该属性,以避免在其他地方重构。
我正在使用 Flask、SQLAlchemy 和 PostgreSQL。
在纯 SQL 中,我尝试做的可能如下所示:
with ancestor as (select hierarchy_hint from node where id='2')
select node.id from node, ancestor
where node.hierarchy_hint and node.level='level4';
在这里,我们希望得到shoes 树中的所有level4 项目,但没有来自任何其他树的level4 项目,也没有来自shoes 的任何level5 等项目。
【问题讨论】:
-
你能否也包括你试图用 SQLAlachemy 模拟的普通 SQL?以及扩展您的表以包含不会通过此关系返回的结果。我不清楚你想用
hierarchy_hint做什么。 -
我想我有一个可以工作的示例,但我不确定它是否正是您想要的。
标签: python sqlalchemy