Search code examples
postgresqlsqlalchemyforeign-keys

It is not possible to establish a connection between the parent and child class


I can't form a relationship between tables, there are no problems when creating tables, but an error occurs when trying to write data from a file:

sqlalchemy.ext.AmbiguousForeignKeysError: Could not determine join condition between parent/child tables on relationship Point.start_point - 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.

`class Point(Base):
    __tablename__ = 'point'

    id_point: Mapped[intpk]
    name_point: Mapped[str100] = mapped_column(unique=True)
    cost: Mapped[int]

    start_point: Mapped[list['Route']] = relationship(back_populates='point_start')
    finish_point: Mapped[list['Route']] = relationship(back_populates='point_finish')


class Route(Base):
    __tablename__ = 'route'

    id_route: Mapped[intpk]
    id_start_point: Mapped[int] = mapped_column(ForeignKey('point.id_point'))
    id_finish_point: Mapped[int] = mapped_column(ForeignKey('point.id_point'))
    distance: Mapped[int]


    point_start: Mapped['Point'] = relationship(back_populates='start_point', foreign_keys='[id_start_point]')
    point_finish: Mapped['Point'] = relationship(back_populates='finish_point', foreign_keys='[id_finish_point]')`

I tried to do it as in the documentation, but it didn't help either

`class Customer(Base):
    __tablename__ = "customer"
    id = mapped_column(Integer, primary_key=True)
    name = mapped_column(String)

    billing_address_id = mapped_column(Integer, ForeignKey("address.id"))
    shipping_address_id = mapped_column(Integer, ForeignKey("address.id"))

    billing_address = relationship("Address", foreign_keys=[billing_address_id])
    shipping_address = relationship("Address", foreign_keys=[shipping_address_id])`

Solution

  • I think these relationships should work.

    
    class Point(Base):
        __tablename__ = 'point'
    
        id_point: Mapped[intpk]
        # These are considered `separate` from the relationships on Route so you have to set the fks here too.
        start_for_routes: Mapped[list['Route']] = relationship(back_populates='point_start', foreign_keys='[Route.id_start_point]')
        finish_for_routes: Mapped[list['Route']] = relationship(back_populates='point_finish', foreign_keys='[Route.id_finish_point]')
    
    
    class Route(Base):
        __tablename__ = 'route'
    
        id_route: Mapped[intpk]
        id_start_point: Mapped[int] = mapped_column(ForeignKey('point.id_point'))
        id_finish_point: Mapped[int] = mapped_column(ForeignKey('point.id_point'))
    
    
        # You can pass in the column in class scope OR...
        point_start: Mapped['Point'] = relationship(back_populates='start_for_routes', foreign_keys=id_start_point)
        # You can use the delayed resolution here too but you have to start with at least a class.
        point_finish: Mapped['Point'] = relationship(back_populates='finish_for_routes', foreign_keys='[Route.id_finish_point]')