SQL / SQLAlchemy «динамические» отношения «один ко многим» с составными первичными ключами - PullRequest
0 голосов
/ 27 июня 2019

Я пытаюсь выяснить, возможно ли это сделать с помощью отношений в декларативном SQLAlchemy (или, если это невозможно, необработанное ядро ​​SQL / SQLAlchemy).

Фон

Я хочу эти две таблицы:

class Allocation:
    id = Column(Integer, primary_key=True) 
    timestamp = Column(DateTime, primary_key=True)
    days = Column(Float)
    employee: Column([a single employee])
class Employees:
    id = Column(Integer, primary_key=True) 
    timestamp = Column(DateTime, primary_key=True)
    name = Column(String(200))
    allocations: Column([a list of allocations])

В идеале мне нужно, чтобы отношения были двунаправленными.

Каждый id относится к версии Сотрудника / Распределения («элемент») во времени. Это позволяет мне отслеживать версии предметов на разные даты. id гарантированно всегда ссылается на один и тот же логический элемент (т. Е. Элементам никогда не потребуется переключаться id). Я могу посмотреть, как выглядел сотрудник с id == 0 на 2019-01-01 с:

e = db.query(Employee).filter(Employee.id == 0) \
  .filter(Employee.timestamp <= datetime(2019,1,1)) \
  .order_by(desc(Employee.timestamp)) \
  .one_or_none()

Осложняющим фактором является то, что отношения должны быть «динамическими» (я не уверен насчет терминологии здесь). Это отношение один ко многим - каждый Allocation всегда имеет ровно один Employee. Однако, в зависимости от желаемой метки времени снимка, которая может измениться строка Employee (так как первоначально назначенный Employee может быть обновлен). Обратное также верно; если я получаю ассигнования на сотрудника, то должны быть возвращены только самые последние ассигнования до запрошенной отметки времени для каждого id.

Пример

Employee row:
id=0
timestamp=2019-01-01
name=Joe Bloggs
allocations=[<allocation 0>]

Employee row:
id=0
timestamp=2019-01-02
name=Joe Rogers
allocations=[<allocation 0>]

Allocation row:
id=0
timestamp=2019-01-01
days=1.5
employee=[<employee 0>]

Если я запрашиваю Распределение 0 с 2019-01-01, мне нужно, чтобы первая запись Сотрудника ("Джо Блоггс") была возвращена вместе с ней. Если это по состоянию на 2019-01-02 или более позднюю, мне нужно, чтобы с ним была возвращена вторая запись сотрудника («Джо Роджерс»).

Вопрос

Это возможно при использовании подзапросов, где в Allocation есть столбец employee_id: если мы хотим, чтобы сотрудник (с отметкой времени) для данного распределения, мы сначала получаем employee_id этого распределения, а затем делаем еще один запрос для этого сотрудника. .

Я хотел бы знать, может ли это быть сделано более эффективно, чем то, что я только что описал, или это за пределами возможностей отношений SQL?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...