求助SQLAlchemy的NoForeignKeysError错误,求ORM模型实用示例
嘿,我来帮你搞定这个SQLAlchemy的错误,顺便给你补些实用的Model操作示例,让你能更顺畅地用起来~
解决
sqlalchemy.exc.NoForeignKeysError错误 你遇到这个错误的核心原因很明确:你的Species类只定义了关联关系(relation),但没有在数据表中添加关联Genus的外键字段。SQLAlchemy需要外键来自动识别两张表的连接条件,没有外键的话,它就不知道怎么把Species和Genus关联起来啦。
下面是修正后的模型代码,我还调整了一些细节(比如用官方推荐的relationship替代relation,优化了__repr__的写法):
from sqlalchemy import Integer, Column, String, ForeignKey from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship Base = declarative_base() class Genus(Base): __tablename__ = 'genus' id = Column(Integer, primary_key=True) common_name = Column(String) scientific_name = Column(String) def __repr__(self): return f"<Genus(scientific_name='{self.scientific_name}')>" # Species is a child of Genus class Species(Base): __tablename__ = 'species' id = Column(Integer, primary_key=True) common_name = Column(String) scientific_name = Column(String) # 关键:添加外键字段,关联Genus表的id主键 genus_id = Column(Integer, ForeignKey('genus.id')) # 现在relationship可以自动识别外键,建立关联;backref会给Genus自动生成species属性,用于反向查询 sc_genus = relationship("Genus", backref="species") def __repr__(self): return f"<Species(scientific_name='{self.scientific_name}')>"
你的addSpecies函数逻辑没问题,我稍微优化了一下写法,让它更简洁:
def addSpecies(session): # 创建属实例 felis_genus = Genus(scientific_name="Felis", common_name="Cats") # 创建物种实例并直接关联属 house_cat = Species( common_name="House Cat", scientific_name="Felis catus", sc_genus=felis_genus ) # 一次性添加多个对象到会话 session.add_all([felis_genus, house_cat]) session.commit()
实用SQLAlchemy Model操作示例
既然你说缺乏Model的使用示例,我整理了几个最常用的操作,帮你快速上手:
1. 查询数据
- 查询所有属:
all_genera = session.query(Genus).all() for genus in all_genera: print(genus)
- 查询某个属的所有物种(利用
backref自动生成的species属性):
felis_genus = session.query(Genus).filter_by(scientific_name="Felis").first() if felis_genus: print(f"属 {felis_genus.scientific_name} 下的物种:") for species in felis_genus.species: print(species)
- 通过物种反向查询所属的属:
house_cat = session.query(Species).filter_by(scientific_name="Felis catus").first() if house_cat: print(f"{house_cat.common_name} 所属的属:{house_cat.sc_genus.scientific_name}")
2. 更新数据
# 修改House Cat的通用名称 house_cat = session.query(Species).filter_by(scientific_name="Felis catus").first() if house_cat: house_cat.common_name = "Domestic Cat" session.commit()
3. 删除数据
# 删除指定物种 house_cat = session.query(Species).filter_by(scientific_name="Felis catus").first() if house_cat: session.delete(house_cat) session.commit()
内容的提问来源于stack exchange,提问作者Andrew Holway
相关产品推荐
相关产品推荐

