AmbiguousForeignKeysError даже после указания foreign_keys - PullRequest
0 голосов
/ 22 мая 2019

Я настраиваю некоторые объекты таблицы для SQLAlchemy.У меня есть пользовательские и контрольные таблицы.Я хочу связать пользовательский объект с checkin и checkout, которые оба записаны в одном и том же объекте checkout, поэтому у меня есть in_user и out_user, связанные с каждым объектом checkout.

Я столкнулся с sqlalchemy.exc.AmbiguousForeignKeysError

Чтобы процитировать точное сообщение об ошибке:

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

Я сделал так, как запрашивает сообщение об ошибке (см. Ниже), но ошибка по-прежнему возникает.

Первоначально я указывал только электронную почту пользователя, потому что хотел иметь возможность удалять пользователей в будущем без повреждения исторических данных.Тем не менее, я попытался добавить идентификатор пользователя, но все равно получил ту же ошибку.

Есть много похожих вопросов о StackOverflow, но я не смог найти тот, который решает мою проблему, и большинство из них работают с гораздо более старымиверсии sqlalchemy, которые не поддерживают аргумент foreign_keys для отношения.Кажется, что это часто происходит с обратными ссылками, но я не использую их, насколько мне известно.Это простая односторонняя ссылка от объекта извлечения до двух пользовательских объектов.

Flask foreign_keys по-прежнему показывает AmbiguousForeignKeysError

sqlalchemy, AmbiguousForeignKeysError

Полный код на github: https://github.com/ACMWM/hwcheckout

Ниже приведен MRE

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

from sqlalchemy import Column, Boolean, Integer, String, ForeignKey, DateTime
from sqlalchemy.orm import relationship

db = "sqlite:///mre.db"
engine = create_engine(db, convert_unicode=True)
db_session = scoped_session(sessionmaker(autocommit=False,
                                         autoflush=False,
                                         bind=engine))

Base = declarative_base()
Base.query = db_session.query_property()

class User(Base):
    __tablename__ = "users"
    id = Column(Integer, primary_key=True)
    email = Column(String)

class HW(Base):
    __tablename__ = "HW"
    id = Column(Integer, primary_key=True)

class Checkout(Base):
    __tablename__ = "Checkouts"

    what = Column(Integer, ForeignKey(HW.id))
    hardware = relationship(HW, foreign_keys=[what])

    id = Column(Integer, primary_key=True)
    out_auth_id = Column(Integer, ForeignKey(User.id))
    out_auth_email = Column(String, ForeignKey(User.email))
    out_auth_user = relationship(User, foreign_keys=[out_auth_id, out_auth_email])

    in_auth_id = Column(Integer, ForeignKey(User.id))
    in_auth_email = Column(String, ForeignKey(User.email))
    in_auth_user = relationship(User, foreign_keys=[in_auth_id, in_auth_email])

Base.metadata.create_all(bind=engine, checkfirst=True)

u = User(email="test@example.com")
chk = Checkout(out_auth_user_id=u.id,out_auth_user_email=u.email)

Я использую SQLAlchemy 1.3.3

РЕДАКТИРОВАТЬ:Убрать двойной импорт моделей.Та же ошибка все еще происходит

Снова отредактируйте: получил MRE для воспроизведения ошибки

Postgres EDIT: Не знаю, помогает ли это, но когда я пытался переместить свой код в реальную базу данных,Я получил эту ошибку:

sqlalchemy.exc.ProgrammingError: (psycopg2.errors.InvalidForeignKey) there is no unique constraint matching given keys for referenced table "users"
[SQL:
 CREATE TABLE "Checkouts" (
         id SERIAL NOT NULL,
         outdate TIMESTAMP WITHOUT TIME ZONE,
         returndate TIMESTAMP WITHOUT TIME ZONE,
         who VARCHAR,
         reason VARCHAR,
         quantity INTEGER,
         what INTEGER,
         out_auth_id INTEGER,
         out_auth_email VARCHAR,
         in_auth_id INTEGER,
         in_auth_email VARCHAR,
         PRIMARY KEY (id),
         UNIQUE (id),
         FOREIGN KEY(what) REFERENCES "HW" (id),
         FOREIGN KEY(out_auth_id) REFERENCES users (id),
         FOREIGN KEY(out_auth_email) REFERENCES users (email),
         FOREIGN KEY(in_auth_id) REFERENCES users (id),
         FOREIGN KEY(in_auth_email) REFERENCES users (email)
 )
]

1 Ответ

0 голосов
/ 23 мая 2019

Попробуйте изменить определение модели Checkout:

class Checkout(Base):
    __tablename__ = "Checkouts"

    what = Column(Integer, ForeignKey(HW.id))
    hardware = relationship(HW, foreign_keys=[what])

    id = Column(Integer, primary_key=True)
    out_auth_id = Column(Integer, ForeignKey(User.id))
    out_auth_email = Column(String, ForeignKey(User.email)) 

    in_auth_id = Column(Integer, ForeignKey(User.id))
    in_auth_email = Column(String, ForeignKey(User.email))

    out_auth_user = relationship('User', foreign_keys=[out_auth_id])
    in_auth_user = relationship('User', foreign_keys=[in_auth_id])

    out_auth_user_by_email = relationship('User', foreign_keys=[out_auth_email])
    in_auth_user_by_email = relationship('User', foreign_keys=[in_auth_email])

Документация: https://docs.sqlalchemy.org/en/13/orm/join_conditions.html#handling-multiple-join-paths

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...