Есть 2 модели (для примера не используется list["Phones"], хотелось просто разобраться в foreign keys.
class Person(Base):
...
work_phone_id: Mapped[int] = mapped_column(ForeignKey("phones.id"))
work_phone: Mapped["Phone"] = relationship(foreign_keys=[work_phone_id])
home_phone_id: Mapped[int] = mapped_column(ForeignKey("phones.id"))
home_phone: Mapped["Phone"] = relationship(foreign_keys=[home_phone_id])
class Phone(Base):
...
number: Mapped[str]
...
На входе есть номер
TEL_NUMBER;
Вопрос: как можно запросом найти Person, у которого TEL_NUMBER указан как home_phone ИЛИ как work_phone.
Пока ничего лучше этого варианта не нашлось:
stmt = (
select(Person)
.options(
selectinload(Person.home_phone), selectinload(Person.work_phone)
)
.where(
Person.home_phone.has(Phone.number == TEL_NUMBER)
| Person.work_phone.has(Phone.number == TEL_NUMBER)
)
)
В этом и следующий случаях используется .has.
Также может сработать, но не совсем кажется корректным:
stmt = (
select(Person)
.join(Phone, Person.work_phone)
.where(
Person.work_phone.has(Phone.number == TEL_NUMBER)
| Person.home_phone.has(Phone.number == TEL_NUMBER)
)
)
Этот запрос не работает без
.join(Phone, Person.work_phone), так как в Person два ForeignKey, приходится указывать один, а связка:
.join(Phone, Person.work_phone)
.join(Phone, Person.home_phone)
Делает join одной таблицы 2 раза, на что тоже ругается SQLAlchemy
Может быть есть какие-то другие варианты?