SQLAlchemy:如何查询自引用邻接列表 table 上的可选列?

SQLAlchemy: How to query an optional column on a self referential adjacency list table?

我有以下 Table 模型表示时间线。

class TimeRange(Base):


    __tablename__ = "time_line"


    record_id = Column(Integer, primary_key=True)
    level = Column(String, nullable=False) # e.g. "Point", "Range"
    content = Column(String, nullable=False)
    language_marker = Column(String) # this one column is optional and needs to be queried
    immediate_parent_id = Column(Integer, ForeignKey('time_line.record_id'))
    child_timelines = relationship('TimeRange', backref=backref('parent_timeline', remote_side=[record_id]))

language_marker列是需要递归查询的列。不是所有的记录都有这样的属性,业务逻辑是:沿着从根到子时间线的层级沿袭,TimeRange实例中至少有一层带有这样的属性,最低的一层应返回水平。这有点像级联样式 sheet,如果 TimeRange 对象本身没有这样的属性,只需向上看一层,util 找到一个,最新定义的样式获胜。

实现此类查询我应该研究的技术方向是什么?我正在使用 SQLAlchemy,后端是 SQLite。谢谢。

我会添加一个 属性 derived_language_marker,它从当前对象开始,沿着父级 TimeRange 的层次结构上升,直到找到一个 language_marker 不是None 和 returns 它:

 @property
 def derived_language_marker(self):
     time_range = self
     while not time_range.language_marker and time_range.parent_timeline:
         time_range = time_range.parent_timeline
     return time_range.language_marker

它可以像 time_range.derived_language_marker 一样访问,但缺点是它可能会导致每个级别的新 SELECT 查询,它检查父对象是否尚未加载。

(如果您为许多 TimeRange 执行此操作并且性能成为问题,您可以使用连接将祖先加载到一定深度,如 here as the long as the maximum possible depth is not too extreme. For further optimization, there is also this approach 所述的 SQLite。)