FastAPI+SQLAlchemy外键约束错误求助:errno:150
排查
errno: 150 "Foreign key constraint is incorrectly formed"错误的额外方向 你已经排查了4项常见问题,下面是几个容易被忽略的原因:
1. 表的创建顺序错误
迁移工具如果先创建子表table_entity,再创建父表db_entity,会因为外键依赖的表不存在而触发错误。
- 检查迁移脚本的执行顺序:确保
db_entity的创建脚本在table_entity之前运行。比如用Alembic时,要保证父表的迁移版本号更早。
2. SQLAlchemy Base类拼写错误
你的代码里写的是Base=declartive_base,正确拼写是declarative_base(缺少字母a)。如果实际代码也是这个错误,会导致DbEntity和TableEntity不属于同一个元数据集合,迁移时子表无法识别父表的db_id列,从而触发外键错误。
- 修正拼写:将
declartive_base改为declarative_base,确保两个表共享同一个Base元数据。
3. 存储引擎不支持外键
MySQL的MyISAM引擎不支持外键约束,必须确保两个表都使用InnoDB引擎。
- 检查表的存储引擎:执行
SHOW CREATE TABLE db_entity;和SHOW CREATE TABLE table_entity;查看ENGINE字段。 - 统一设置存储引擎:在SQLAlchemy的表定义中添加
__table_args__指定引擎,示例:__table_args__ = {"mysql_engine": "InnoDB"}
4. 字符排序规则(Collation)不一致
即使字符集一致,排序规则不同也会导致外键错误(比如父表是utf8mb4_general_ci,子表是utf8mb4_bin)。
- 检查排序规则:执行
SHOW FULL COLUMNS FROM db_entity LIKE 'db_id';和SHOW FULL COLUMNS FROM table_entity LIKE 'db_id';,对比Collation字段是否一致。 - 统一排序规则:在列定义中显式指定,示例:
db_id = Column(String(24), unique=True, nullable=False, comment="DB ID", collation="utf8mb4_general_ci")
5. 父表的db_id列索引异常
虽然unique=True会自动创建索引,但如果索引被手动删除或者创建过程中出现异常,也会导致外键无法关联。
- 检查父表索引:执行
SHOW INDEX FROM db_entity;,确认db_id列存在对应的唯一索引。
内容的提问来源于stack exchange,提问作者Wonseok Choi
相关产品推荐
相关产品推荐

