У меня сложная модель. Допустим, он содержит 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))
Теперь я хочу вернуть сущности через конечные точки отдыха в колбе. Итак, 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
во время определения класса, поскольку он передается во время выполнения. Я думал о некоторых хаках для этого, таких как переопределение всего во время каждой среды выполнения, но я не доволен ими. У кого-нибудь есть понимание относительно "правильного" способа сделать что-то подобное?