@oslik_ppc

Как сделать корректный SELECT запрос с 2-я ForeignKey?

Есть 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

Может быть есть какие-то другие варианты?
  • Вопрос задан
  • 113 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы