我有一个复杂的模型。假设它包含100个实体,所有实体都以某种方式相互关联。有些是多对多的,有些是一对一的,有些是多对一的,依此类推。
这些实体都具有start
和end
时间戳,指示有效时间范围。通过查询加载这些实体时,我希望仅使用具有start
和end
标记并包裹给定时间戳记的实体来填充关系字段:例如datetime.now()
或昨天,或在任何时候。
例如,我将在此处定义两个模型,但假设有很多其他模型:
class User(base):
__tablename__ = 'User'
class Role(base):
__tablename__ = 'Role'
user_id = Column(Integer, ForeignKey('User.uid'))
user = relationship(User, backref=backref('Role')
start = Column(DateTime, default=func.current_timestamp())
end = Column(DateTime))
现在,我想通过flask中的宁静端点返回实体。因此,get
在烧瓶中可能看起来像这样:
def get(self, uid=None) -> Tuple[Dict, int]:
query = User.query
if uid:
query.filter_by(uid=uid)
return create_response(
query.all()
200
)
现在,我想将作为子级返回的Role
实体限制为上述查询返回的User
。显然,只要扩展query
来过滤角色,就可以轻松实现。当规模扩大时,问题就来了。考虑100个嵌套的子级关系。现在考虑为每个端点提供get
的静态端点。几乎不可能写出query
来正确过滤每个不同级别的孩子。
我想要的解决方案是在每个实体上定义加载行为,使所有内容都可组合。例如:
class User(base):
__tablename__ = 'User'
role = relationship("Role",
primaryjoin="and_(Role.start<={desired_timestamp} "
"Role.end>={desired_timestamp})")
当然,问题在于我们在类定义时不知道我们的desired_timestamp
,因为它是在运行时传递的。我想到了一些技巧,例如在每个运行时重新定义所有内容,但我对它们不满意。是否有人对做这样的事情的“正确”方法有所了解?