Можно ли сделать двойную связь Many-To-Many и One-To-Many в SQLAlchemy?

Делаю что-то вроде todo-листа, чтобы разобраться с SQLAlchemy. Сделал 3 таблицы - для пользователей, для листов пользователей и для задач пользователей.

Пытаюсь реализовать связи так, чтобы реализовать такие функциональности:

  • Many-To-Many у задач и листов, чтобы можно было связывать листы с задачами
  • Many-To-Many у задач и пользователей, чтобы пользователи могли отмечать задачи, которые они сделали или например не хотят делать
  • Many-To-Many у пользователей и листов, чтобы пользователям можно было сохранять чужие листы к себе

Но еще мне нужно сделать так, чтобы лист хранил в себе пользователя-автора, чтобы когда этот лист сохранил к себе кто-то другой, авторство оставалось за первым пользователем. Но как это можно сделать?

Сейчас реализовал всё так:

class TaskStatus(int, enum.Enum):
    TODO = 0
    DONE = 1
    NOT_INTERESTED = 2


class UserTodolistLink(SQLModel, table=True):
    user_id: UUID | None = Field(default=None, foreign_key="user.id", primary_key=True)
    todolist_id: UUID | None = Field(default=None, foreign_key="todolist.id", primary_key=True)


class UserTaskLink(SQLModel, table=True):
    user_id: UUID | None = Field(default=None, foreign_key="user.id", primary_key=True)
    task_id: UUID | None = Field(default=None, foreign_key="task.id", primary_key=True)
    status: TaskStatus = Column(Enum(TaskStatus))


class TodolistTaskLink(SQLModel, table=True):
    todolist_id: UUID | None = Field(default=None, foreign_key="todolist.id", primary_key=True)
    task_id: UUID | None = Field(default=None, foreign_key="task.id", primary_key=True)


class User(SQLModel, table=True):
    id: UUID = Field(primary_key=True, default_factory=uuid4)
    username: str
    todolists: list[Todolist] = Relationship(link_model=UserTodolistLink, back_populates="users")
    tasks: list[Task] = Relationship(link_model=UserTaskLink, back_populates="users")


class Todolist(SQLModel, table=True):
    id: UUID = Field(primary_key=True, default_factory=uuid4)
    name: str
    author_id: UUID
    users: list[User] = Relationship(link_model=UserTodolistLink, back_populates="todolists")
    tasks: list[Task] = Relationship(link_model=TodolistTaskLink, back_populates="todolists")


class Task(SQLModel, table=True):
    id: UUID = Field(primary_key=True, default_factory=uuid4)
    name: str
    users: list[User] = Relationship(link_model=UserTaskLink, back_populates="tasks")
    todolists: list[Todolist] = Relationship(link_model=TodolistTaskLink, back_populates="tasks")

Проблема тут в том, что чтобы мне получить автора листа мне нужно делать еще один запрос. Думал, что можно сделать JOIN, но для этого нужно ведь еще настраивать связь One-To-Many. Но возможно ли это, чтобы было две связи у таблиц?


Ответы (0 шт):