SQLAlchemy 1.2.7:无需定义类创建新表及FK关联报错解决咨询
解决SQLAlchemy declarative API中的NoReferencedTableError错误
这个错误我之前也碰到过,本质就是你定义的外键找不到对应的目标表,结合你说的场景,大概率是模型定义顺序、外键写法或者模型继承的问题,下面给你拆解几个常见原因和对应的解决办法:
常见原因1:模型定义顺序搞反了
如果你的OrgPrediction类写在了Organization类前面,SQLAlchemy在执行Base.metadata.create_all(engine)的时候,会先尝试创建org_prediction表,但此时organization表还没被注册到元数据里,自然找不到,就会触发这个错误。
错误示例
from sqlalchemy import Column, Integer, String, ForeignKey from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship Base = declarative_base() # 先写了依赖的OrgPrediction,后写被依赖的Organization class OrgPrediction(Base): __tablename__ = 'org_prediction' id = Column(Integer, primary_key=True) company_id = Column(Integer, ForeignKey('organization.id')) prediction = Column(String) organization = relationship("Organization") class Organization(Base): __tablename__ = 'organization' id = Column(Integer, primary_key=True) name = Column(String)
解决办法:调整定义顺序
把被依赖的Organization类放在前面,让SQLAlchemy先处理它的表:
Base = declarative_base() # 先定义被依赖的Organization class Organization(Base): __tablename__ = 'organization' id = Column(Integer, primary_key=True) name = Column(String) # 可以加上反向关联,让关系更清晰 predictions = relationship("OrgPrediction", back_populates="organization") # 再定义依赖的OrgPrediction class OrgPrediction(Base): __tablename__ = 'org_prediction' id = Column(Integer, primary_key=True) company_id = Column(Integer, ForeignKey('organization.id')) prediction = Column(String) organization = relationship("Organization", back_populates="predictions")
常见原因2:外键写法没用到延迟解析
如果不想调整类的定义顺序,你可以用类名.属性名的形式写外键,SQLAlchemy会自动延迟解析这个外键,等所有模型都加载完成后再处理,这样就不会因为顺序问题报错了。
示例代码
Base = declarative_base() class OrgPrediction(Base): __tablename__ = 'org_prediction' id = Column(Integer, primary_key=True) # 这里用类名Organization代替表名organization company_id = Column(Integer, ForeignKey('Organization.id')) prediction = Column(String) organization = relationship("Organization") class Organization(Base): __tablename__ = 'organization' id = Column(Integer, primary_key=True) name = Column(String)
常见原因3:被引用的模型没继承Base
如果你的Organization类忘记继承你定义的declarative base(比如上面的Base),那它的表根本不会被加入到Base.metadata中,执行create_all的时候不会创建这个表,外键自然找不到。
错误示例
# 这里少了继承Base! class Organization: __tablename__ = 'organization' id = Column(Integer, primary_key=True) name = Column(String)
解决办法:补全继承
把类改成继承Base的形式:
class Organization(Base): __tablename__ = 'organization' id = Column(Integer, primary_key=True) name = Column(String)
常见原因4:表名拼写错误
如果你的Organization模型的__tablename__是organizations(复数),但外键里写的是organization.id,那肯定会找不到表,要确保外键里的表名和模型的__tablename__完全一致。
示例代码
class Organization(Base): __tablename__ = 'organizations' # 表名是复数 id = Column(Integer, primary_key=True) name = Column(String) class OrgPrediction(Base): __tablename__ = 'org_prediction' id = Column(Integer, primary_key=True) # 外键里的表名要和上面的__tablename__一致 company_id = Column(Integer, ForeignKey('organizations.id')) prediction = Column(String) organization = relationship("Organization")
内容的提问来源于stack exchange,提问作者tandy
相关产品推荐
相关产品推荐

