簡體   English   中英

無法在flask-sqlalchemy中創建自引用外鍵

[英]Unable to create self referencing foreign key in flask-sqlalchemy

我有一個模型Region ,每個Region可以有子區域。 每個子區域都有一個字段parent_id ,它是其父區域的id。 這是我的模型的樣子

class Region(db.Model):
    __tablename__ = 'regions'
    __table_args__ = {'schema': 'schema_name'}
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100))
    parent_id = db.Column(db.Integer, db.ForeignKey('regions.id'))
    parent = db.relationship('Region', primaryjoin=('Region.parent_id==Region.id'), backref='sub-regions')
    created_at = db.Column(db.DateTime, default=db.func.now())
    deleted_at = db.Column(db.DateTime)

當我嘗試db.create_all我得到此錯誤db.create_all sqlalchemy.exc.NoReferencedTableError: Foreign key associated with column 'regions.parent_id' could not find table 'regions' with which to generate a foreign key to target column 'id'

當我在__tablename__指定regions時,為什么無法找到regions 我正在使用flask-sqlalchemy 1.0版

編輯 - 我刪除了該行

__table_args__ = {'schema': 'schema_name'}

從我的代碼,它的工作原理。 打敗了我。

您必須告訴SQLAlchemy關系的“遠程端”是什么,以區分當前行和要連接的行。 相關解釋位於關系關系文檔的這一部分的中間位置。

這種關系可能如下所示:

parent = db.relationship('Region', remote_side=id, backref='sub_regions')

這是一個展示自我指涉關系的例子:

from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.engine import create_engine
from sqlalchemy.ext.declarative.api import declarative_base
from sqlalchemy.orm import sessionmaker, relationship

engine = create_engine('sqlite:///:memory:', echo=True)
Session = sessionmaker(engine)
Base = declarative_base(engine)

session = Session()


class Region(Base):
    __tablename__ = 'region'

    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)
    parent_id = Column(Integer, ForeignKey('region.id'), index=True)

    parent = relationship(lambda: Region, remote_side=id, backref='sub_regions')


Base.metadata.create_all()

r1 = Region(name='United States of America')
r2 = Region(name='California', parent=r1)

session.add_all((r1, r2))
session.commit()

ca = session.query(Region).filter_by(name='California').first()
print ca.parent.name

自啟用echo以來,將會有許多SQL輸出行,腳本將在末尾打印“美國”。

我對模式名稱參數有同樣的問題。 我改變它的工作原理是直接在ForeignKey和關系中引用表類而不是使用字符串。 例:

parent_id = Column(Integer, ForeignKey(Region.id), index=True)

parent = relationship(lambda: Region, remote_side=id, backref='sub_regions')

我只看到與@davidism的細微差別,但這對我來說直接在SQLAlchemy中有用。

from sqlalchemy import Column
from sqlalchemy import Integer
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.orm import backref

class Region(Base):
  __tablename__ = 'region'

  id = Column(Integer, primary_key=True)
  parent_id = Column(Integer, ForeignKey('region.id'), index=True)
  sub_regions = relationship('Region', backref=backref('parent', remote_side='Region.id'))

正如他指出的那樣,我猜你不會需要導入,但是應該用db前綴,所以類似於:

class Region(db.Model):
  __tablename__ = 'region'

  id = db.Column(db.Integer, primary_key=True)
  parent_id = db.Column(db.Integer, db.ForeignKey('region.id'), index=True)
  sub_regions = db.relationship('Region', backref=db.backref('parent', remote_side='Region.id'))

如果對任何表使用模式,則具有引用這些模式表的外鍵的其他表必須提供模式的名稱。 請參閱此處的文檔

class Table(db.Model):
    __tablename__ = 'table_1_name'
    __table_args__ = {'schema': 'my_schema'}

    id = Column('id', Integer, primary_key=True)
    ...

class AnotherTable(db.Model):
    __tablename__ = 'table_2_name'
    # Doesn't matter if this belongs to the same or different schema
    # __table_args__ = {'schema': 'my_schema'}

    id = Column('id', Integer, primary_key=True)
    t1_id = Column(Integer, ForeignKey('my_schema.table_1_name.id'))
    ...

適用於SQLAlchemy和Flask-SQLAlchemy。 希望這可以幫助。 :d

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM