我有以下表示时间轴的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。谢谢。
我将添加一个属性derived_language_marker
,它从当前对象开始,向上扩展父TimeRange
s的层次结构,直到它找到一个不是None
的language_marker并返回它:
@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
执行此操作并且性能成为问题,则可以使用此处描述的连接将祖先加载到一定深度,只要最大可能深度不是太极端。)为了进一步优化,SQLite也有这种方法