Я настраиваю некоторые объекты таблицы для 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)
)
]