class User(Base):
__tablename__ = "user"
id = Column(Integer, primary_key=True)
address_first_id = Column(Integer, ForeignKey('address.id'))
address_first = relationship("Address", foreign_keys=[address_first_id], back_populates="u_first_address", lazy='subquery')
address_second_id = Column(Integer, ForeignKey('address.id'))
address_second = relationship("Address", foreign_keys=[address_second _id], back_populates="u_second_address", lazy='subquery')
is_available = Column(Boolean, unique=False, default=True)
created_at = Column(DateTime, index=True, server_default=func.now())
update_at = Column(DateTime, index=True, server_default=func.now(), server_onupdate=func.now())
class Address(Base):
__tablename__ = "address"
id = Column(Integer, primary_key=True)
comment = Column(String(100), unique=True, nullable=False)
u_first_address = relationship("User", lazy='subquery', back_populates="address_first", primaryjoin="User.address_first_id == Address.id")
u_second_address = relationship("User", lazy='subquery', back_populates="address_second", primaryjoin="User.address_first_id == Address.id")
is_available = Column(Boolean, unique=False, default=True)
created_at = Column(DateTime, index=True, server_default=func.now())
update_at = Column(DateTime, index=True, server_default=func.now(), server_onupdate=func.now())
sqlalchemy.exc.AmbiguousForeignKeysError: Could not determine join condition between parent/child tables on relationship Address.u_first_address - there are multiple foreign key paths linking the tables. Specify the 'foreign_keys' argument, providing a list of those columns which should be counted as containing a foreign key reference to the parent table.
Такая ошибка у меня в консоли, прогуглил, пишут что нужно идти через backref, крутил и так и сяк, видно не хватает теоретических знаний.#!/usr/bin/env python
from datetime import datetime
from sqlalchemy import ForeignKey
from sqlalchemy import create_engine, delete, select, update
from sqlalchemy.orm import DeclarativeBase, Mapped
from sqlalchemy.orm import mapped_column, relationship, sessionmaker
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = "user"
id: Mapped[int] = mapped_column(primary_key=True)
address_first_id: Mapped[int] = mapped_column(ForeignKey('address.id'))
address_first: Mapped["Address"] = relationship(foreign_keys=[address_first_id])
address_second_id: Mapped[int] = mapped_column(ForeignKey('address.id'))
address_second: Mapped["Address"] = relationship(foreign_keys=[address_second_id])
is_available: Mapped[bool] = mapped_column(default=True)
created_on: Mapped[datetime] = mapped_column(default=datetime.utcnow())
updated_on: Mapped[datetime] = mapped_column(default=datetime.utcnow(), onupdate=datetime.utcnow())
class Address(Base):
__tablename__ = "address"
id: Mapped[int] = mapped_column(primary_key=True)
comment: Mapped[str] = mapped_column(unique=True, nullable=False)
is_available: Mapped[bool] = mapped_column(default=True)
created_on: Mapped[datetime] = mapped_column(default=datetime.utcnow())
updated_on: Mapped[datetime] = mapped_column(default=datetime.utcnow(), onupdate=datetime.utcnow())
if __name__ == "__main__":
engine = create_engine('sqlite:///:memory:', echo=True)
Base.metadata.create_all(engine)
Session = sessionmaker(engine)
# добавим пользователя с двумя адресами
with Session.begin() as session:
address1 = Address(comment="Lenina 45")
address2 = Address(comment="Sedina 5")
user = User(address_first=address1, address_second=address2)
session.add(user)
# проверим, что пользователь был создан успешно
with Session.begin() as session:
user = session.query(User).first()
print(user, user.address_first.comment)
with Session.begin() as session:
# находим первый адрес по части адреса
adr = session.query(Address).where(Address.comment.like("%Sedina%")).first()
print(adr, adr.comment)
# находим первого пользователя у которого один из адресов соответствует найденному выше адресу
usr = session.query(User).where(User.address_first == adr or User.address_second == adr).first()
print(usr, usr.address_first.comment, usr.address_second.comment)