我有以下代表时间轴的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
实例的至少一个级别具有这样的属性,而最低级别的一个属性具有这样的属性。水平应该返回。这有点像级联样式表,如果TimeRange
对象本身没有这样的属性,只需向上看一级,找到一个,最新定义的样式获胜。
我应该考虑实施此类查询的技术方向是什么?我使用的是SQLAlchemy,后端是SQLite。感谢。
答案 0 :(得分:1)
我会添加一个以当前对象开头的属性derived_language_marker
并上升到父TimeRange
的层次结构,直到它找到一个不是None
的language_marker并返回它:< / p>
@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所述的连接急切地将祖先加载到某个深度。并不是太极端。为了进一步优化,SQLite还有this approach。)