Можно ли сделать двойную связь 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. Но возможно ли это, чтобы было две связи у таблиц?