Python 将嵌套的子对象过滤到任意深度
我有一个复杂的模型。假设它包含100个实体,所有这些实体都以某种方式相互关联。有些是多对多,有些是一对一,有些是多对一,等等 这些实体都具有指示有效时间范围的Python 将嵌套的子对象过滤到任意深度,python,flask,sqlalchemy,Python,Flask,Sqlalchemy,我有一个复杂的模型。假设它包含100个实体,所有这些实体都以某种方式相互关联。有些是多对多,有些是一对一,有些是多对一,等等 这些实体都具有指示有效时间范围的start和end时间戳。当通过查询加载这些实体时,我希望仅使用具有包装给定时间戳的start和end戳记的实体填充关系字段:例如datetime.now(),或昨天,或任何时候 例如,我将在这里定义两个模型,但假设还有大量其他模型: class User(base): __tablename__ = 'User' class R
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中的restful端点返回实体。因此,get
在flask中可能看起来像这样:
def get(self, uid=None) -> Tuple[Dict, int]:
query = User.query
if uid:
query.filter_by(uid=uid)
return create_response(
query.all()
200
)
现在,我想将作为子级返回的角色
实体限制为上述查询返回的用户
。显然,只需扩展查询
来过滤角色,就可以轻松实现这一点。当这种情况扩大时,问题就来了。考虑100个嵌套级别的子关系。现在考虑REST端点为它们中的任何一个提供<代码>获取< /代码>。几乎不可能写出一个查询
来正确过滤每个不同级别的子级
我想要的解决方案是在每个实体上定义加载行为,使所有内容都可组合。例如:
class User(base):
__tablename__ = 'User'
role = relationship("Role",
primaryjoin="and_(Role.start<={desired_timestamp} "
"Role.end>={desired_timestamp})")
类用户(基本):
__tablename_uu='User'
角色=关系(“角色”,
primaryjoin=“and(Role.start={所需的\u时间戳})”)
当然,问题是我们在类定义时不知道所需的时间戳,因为它是在运行时传递的。我已经想到了一些解决方法,比如在每次运行时都重新定义所有内容,但我对它们不满意。有人对这样做的“正确”方法有什么见解吗?我的想法是在
get()
中对用户进行子类化,定义子类上的角色关系,以便在知道所需的时间戳后可以指定文本主联接。然后查询子类。免责声明是,我不在电脑前,所以还没有尝试过!如果执行TIH,则必须以类似的方式为其他100个子关系定义关系,并为每个资源(其中每个实体有一个,所以再次为100个)上的get定义关系。这与在get中定义复杂查询的问题类似,但您的“期望行为”表明您希望在实体上定义关系。这也没什么不同,只是在get()
func中完成。不管怎样,在实体上定义这么多关系,您肯定会找到一种方法来概括类的创建,也许可以使用带有3个参数的type()
?还有一个更通用的get()
,而不是定义100条执行类似操作的路由?至少这是我想走的路,但是我可能还是不明白你的问题的范围。我的想法是在get()
中对User
进行子类化,定义子类上的role
关系,以便在知道所需的时间戳后可以指定文本主联接。然后查询子类。免责声明是,我不在电脑前,所以还没有尝试过!如果执行TIH,则必须以类似的方式为其他100个子关系定义关系,并为每个资源(其中每个实体有一个,所以再次为100个)上的get定义关系。这与在get中定义复杂查询的问题类似,但您的“期望行为”表明您希望在实体上定义关系。这也没什么不同,只是在get()
func中完成。不管怎样,在实体上定义这么多关系,您肯定会找到一种方法来概括类的创建,也许可以使用带有3个参数的type()
?还有一个更通用的get()
,而不是定义100条执行类似操作的路由?至少这是我想走的路,但我可能不明白你的问题的范围。