Python 将嵌套的子对象过滤到任意深度

Python 将嵌套的子对象过滤到任意深度,python,flask,sqlalchemy,Python,Flask,Sqlalchemy,我有一个复杂的模型。假设它包含100个实体,所有这些实体都以某种方式相互关联。有些是多对多,有些是一对一,有些是多对一,等等 这些实体都具有指示有效时间范围的start和end时间戳。当通过查询加载这些实体时,我希望仅使用具有包装给定时间戳的start和end戳记的实体填充关系字段:例如datetime.now(),或昨天,或任何时候 例如,我将在这里定义两个模型,但假设还有大量其他模型: class User(base): __tablename__ = 'User' class R

我有一个复杂的模型。假设它包含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中的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条执行类似操作的路由?至少这是我想走的路,但我可能不明白你的问题的范围。