Возьмите следующая схема, в которую еще не добавлен дополнительный ключ соединения:
Код: Выделить всё
from typing import List
from uuid import UUID
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
from sqlalchemy.schema import ForeignKey
from sqlalchemy.types import Uuid
import sqlalchemy as sa
class Base(DeclarativeBase): pass
class User(Base):
__tablename__ = 'user'
id: Mapped[UUID] = mapped_column(Uuid(), primary_key=True)
tenant_id: Mapped[UUID] = mapped_column(Uuid())
actions: Mapped[List["Action"]] = relationship("Action", back_populates="user", foreign_keys="Action.user_id")
class Action(Base):
__tablename__ = 'action'
id: Mapped[UUID] = mapped_column(Uuid(), primary_key=True)
tenant_id: Mapped[UUID] = mapped_column(Uuid())
user_id: Mapped[UUID] = mapped_column(Uuid(), ForeignKey("user.id"))
user: Mapped["User"] = relationship("User", back_populates="actions", foreign_keys=[user_id])
Base.metadata.create_all(sa.create_engine('sqlite://', echo=True))
Код: Выделить всё
class User(Base):
__tablename__ = "user"
id: Mapped[UUID] = mapped_column(Uuid(), primary_key=True)
tenant_id: Mapped[UUID] = mapped_column(Uuid())
actions: Mapped["Action"] = relationship("Action",
back_populates="user",
foreign_keys="Action.user_id",
primaryjoin="and_(tenant_id == Action.tenant_id, id == Action.user_id)",
)
class Action(Base):
__tablename__ = "action"
id: Mapped[UUID] = mapped_column(Uuid(), primary_key=True)
tenant_id: Mapped[UUID] = mapped_column(Uuid())
user_id: Mapped[UUID] = mapped_column(Uuid(), ForeignKey("user.id"))
user: Mapped["User"] = relationship("User",
back_populates="actions",
foreign_keys=[user_id],
primaryjoin=sa.and_(tenant_id == User.tenant_id, user_id == User.id),
)
Если бы мы могли предоставить код, который оценивается после определения всех типов, но до SQLAlchemy начинает самоанализ, который позволит использовать вспомогательную функцию для генерации отношений. Это по-прежнему не подходит для статической проверки, но это значительно лучше, чем ничего. Однако я не знаю, произойдет ли соответствующий самоанализ (если отношения должны существовать при вызове __init_subclass__), любая попытка добавить их позже будет слишком поздно ).
SQLAlchemy имеет ряд возможностей, с которыми я сразу не знаком, поэтому надеюсь, что есть вариант, о котором я здесь не думаю.
Подробнее здесь: https://stackoverflow.com/questions/791 ... efer-to-ta