SQLAlchemy多对一关联报错NoReferencedTableError,求问题排查
问题分析与解决
你的错误核心是在ForeignKeyConstraint里引用了Python类名OntologyVersion,但SQLAlchemy生成外键时需要对应数据库的表名ontology_version(也就是你在__tablename__里定义的名称)。另外还有几个小细节需要调整,我一步步给你梳理:
1. 复合外键的表名引用错误
你原来的代码里写了:
ForeignKeyConstraint( ['ontology_name', 'ontology_version'], ['OntologyVersion.name', 'OntologyVersion.version'], ),
这里必须把OntologyVersion.name改成ontology_version.name——SQLAlchemy是和数据库表直接交互的,它认的是你定义的表名,不是Python类的名字。
2. 重复定义外键冗余
你已经通过ForeignKeyConstraint定义了复合外键,就不需要再给ontology_name和ontology_version单独加ForeignKey注解了,这会造成冗余,甚至可能引发逻辑冲突。
3. 未定义QueryResultAssertion的主键
SQLAlchemy要求每个模型必须有主键,你的QueryResultAssertion里只定义了node_id但没把它设为主键,这会导致建表操作失败。
修正后的完整代码
from sqlalchemy import Column, String, ForeignKeyConstraint, create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship, sessionmaker Base = declarative_base() class OntologyVersion(Base): __tablename__ = 'ontology_version' name = Column(String, primary_key=True) version = Column(String, primary_key=True) # 添加反向引用,方便双向查询 children = relationship('QueryResultAssertion', back_populates='ontology') class QueryResultAssertion(Base): __tablename__ = 'query_results' # 设置主键,如果node_id不唯一,可改成(node_id, ontology_name, ontology_version)组合主键 node_id = Column(String, primary_key=True) ontology_name = Column(String) ontology_version = Column(String) # 和OntologyVersion的children建立双向关联 ontology = relationship('OntologyVersion', back_populates='children') __table_args__ = ( ForeignKeyConstraint( ['ontology_name', 'ontology_version'], ['ontology_version.name', 'ontology_version.version'], ), ) Session = sessionmaker() engine = create_engine('sqlite:///:memory:', echo=True) Base.metadata.create_all(bind=engine)
额外补充
我给关系添加了back_populates,这样你可以通过OntologyVersion实例直接访问它关联的children集合,也能通过QueryResultAssertion实例快速拿到对应的ontology对象,后续查询会更顺畅。
内容的提问来源于stack exchange,提问作者user1598231
相关产品推荐
相关产品推荐

