【问题标题】:SqlAlchemy Error on Creating multiple foreign key to one table为一张表创建多个外键时出现 SqlAlchemy 错误
【发布时间】:2019-05-22 20:37:22
【问题描述】:

我是使用 sqlAlchemy 的新手,在创建新表时遇到问题,特别是当涉及到 2 个指向 1 个表的外键时:

class Offers(db.Model):
    __tablename__ = 'offers'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    contact_ign = db.Column(db.String(100))
    conversion_rate = db.Column(db.Float)
    stock = db.Column(db.Integer)
    create_date = db.Column(db.DateTime(timezone=True), default=func.now())
    currency_pair = db.relationship('CurrencyPairs', backref='pair', lazy='dynamic')

class CurrencyPairs(db.Model):
    __tablename__ = 'currency_pairs'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    league = db.Column(db.String(100))
    pair_id = db.Column(db.Integer, db.ForeignKey('offers.id'))
    want = db.relationship('Currency', backref='want', lazy='dynamic')
    have = db.relationship('Currency', backref='have', lazy='dynamic')

class Currency(db.Model):
    __tablename__ = 'currency'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(100), nullable=False)
    poe_trade = db.Column(db.Integer, nullable=False)
    poe_official = db.Column(db.String(10), nullable=False)
    tier = db.Column(db.Integer, nullable=False)
    want_id = db.Column(db.Integer, db.ForeignKey('currency_pairs.id'))
    have_id = db.Column(db.Integer, db.ForeignKey('currency_pairs.id'))

我得到的错误是:

sqlalchemy.exc.InvalidRequestError: One or more mappers failed to initialize - can't proceed with initialization of other mappers. Triggering mapper: 'Mapper|CurrencyPairs|currency_pairs'. Original exception was: Could not determine join condition b
etween parent/child tables on relationship CurrencyPairs.want - 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 refe
rence to the parent table

我尝试了不同的东西,但得到了相同的结果。 我究竟做错了什么? 提前致谢。

【问题讨论】:

标签: python sqlalchemy flask-sqlalchemy


【解决方案1】:

我知道这是一个老问题,但我遇到了同样的问题。我希望能帮助其他人回答。

这个问题在 sqlalchemy 文档中得到解决。

https://docs.sqlalchemy.org/en/13/orm/join_conditions.html#handling-multiple-join-paths

class Offers(db.Model):
    __tablename__ = 'offers'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    contact_ign = db.Column(db.String(100))
    conversion_rate = db.Column(db.Float)
    stock = db.Column(db.Integer)
    create_date = db.Column(db.DateTime(timezone=True), default=func.now())
    currency_pair = db.relationship('CurrencyPairs', backref='pair', lazy='dynamic')

class CurrencyPairs(db.Model):
    __tablename__ = 'currency_pairs'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    league = db.Column(db.String(100))
    pair_id = db.Column(db.Integer, db.ForeignKey('offers.id'))

    want_currency = relationship("Currency", foreign_keys='[Currency.want_id]', back_populates="want_currency_pairs")
    have_currency = relationship("Currency", foreign_keys='[Currency.have_id]', back_populates="have_currency_pairs")

class Currency(db.Model):
    __tablename__ = 'currency'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(100), nullable=False)
    poe_trade = db.Column(db.Integer, nullable=False)
    poe_official = db.Column(db.String(10), nullable=False)
    tier = db.Column(db.Integer, nullable=False)

    want_currency_pairs = relationship(CurrencyPairs, foreign_keys="[Currency.want_id]", back_populates="want_currency")
    have_currency_pairs = relationship(CurrencyPairs, foreign_keys="[Currency.have_id]", back_populates="have_currency")

你写代码的方式,sqlalchemy并不能真正理解选择哪个关系,因为你有2个相同的关系。所以你必须向 sqlalchemy 描述同一张表有 2 个关系。

【讨论】:

    猜你喜欢
    • 2013-06-03
    • 2014-11-09
    • 2019-02-20
    • 2016-06-25
    • 2019-09-15
    • 1970-01-01
    • 2021-05-02
    • 1970-01-01
    • 2022-11-14
    相关资源
    最近更新 更多