You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django创建外键约束报150错误及数据库层级级联删除设置咨询

问题1:外键约束创建失败(errno 150 "Foreign key constraint is incorrectly formed")

报错原因

MySQL要求外键字段和被引用的主键字段类型完全匹配。你自定义的TinyIntField继承自AutoField,AutoField默认对应int类型,Django生成外键字段时会默认按照父类AutoField的类型创建int类型的外键,和tblroles表实际tinyint类型的role_id不匹配,因此触发报错。

解决方法

自定义TinyIntField时新增rel_db_type方法,显式指定外键关联时的匹配字段类型,修改后的自定义字段代码如下:

class TinyIntField(AutoField):
    def db_type(self, connection):
        return "tinyint(3) AUTO_INCREMENT"
    # 新增该方法指定关联字段类型
    def rel_db_type(self, connection):
        return "tinyint(3)"

修改完成后删除已生成的错误迁移文件,重新执行python manage.py makemigrations和python manage.py migrate即可。


问题2:on_delete CASCADE未在数据库层面生效

原因

Django默认会在ORM层面处理级联删除逻辑,若要在数据库层面生成级联删除约束,需要确保外键配置和数据库全局配置都符合要求。

解决方法

第一步:修改外键配置

给ForeignKey显式指定db_constraint=True参数,该参数默认值为True,若之前有手动关闭需要重新开启:

class tblusers(models.Model):
    user_id = BigAutoField(primary_key=True)
    # 新增db_constraint=True参数
    role = ForeignKey(tblroles, on_delete = models.CASCADE, db_constraint=True)

第二步:检查数据库全局配置

打开settings.py查看数据库配置,确认没有关闭外键约束的配置,比如移除如下配置项:

# 要删除的关闭外键配置
OPTIONS = {"init_command": "SET foreign_key_checks = 0"}

第三步:重新生成迁移

删除旧的迁移文件,重新执行迁移命令,此时数据库层面就会生成带级联删除的外键约束。

内容的提问来源于stack exchange,提问作者Pankaj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 01:06:03