Django迁移报错3780:外键关联字段类型不兼容问题排查
问题核心
你遇到的OperationalError: 3780是因为外键字段ciudad_id(bigint类型)与关联表Città的主键id(int类型)类型不匹配。Django 3.2+默认将自增主键从AutoField(对应int)改为BigAutoField(对应bigint),但老表Città的主键仍为int,新创建的外键默认采用了新的bigint类型,导致类型冲突。
针对你的三个假设的解答
迁移是否忽略配置导致字段类型未切换为int?
是的,DEFAULT_AUTO_FIELD仅控制新创建的自增主键字段的默认类型,不会自动修改外键字段的类型。即使你在settings或AppConfig中设置了该配置,外键的类型仍由关联模型的主键类型推导(或默认采用当前Django的自增字段类型),因此无法解决外键类型不匹配的问题。DEFAULT_AUTO_FIELD对外键是否有特殊影响?
没有直接影响。该配置只作用于自增主键,外键字段的类型默认跟随关联模型的主键类型,除非你显式指定字段类型。这就是你设置后问题仍存在的原因。是否存在未发现的排序规则差异?
从错误提示来看,核心矛盾是字段类型不兼容,排序规则差异通常会引发其他类型的报错(如字符排序不匹配)。你可以通过数据库命令确认:
-- 查看Città表主键类型 DESCRIBE city_search_città; -- 查看Manifestazione表外键类型(若迁移已生成表) DESCRIBE eventos_manifestazione;
对比两表字段的Type列,若排序规则(Collation列)一致,即可排除该可能性。
具体解决方案
方案1:显式指定外键的数据库类型(快速修复)
直接在Manifestazione模型的外键定义中指定db_type,强制匹配Città的主键类型:
from django.db import models import schedule class Manifestazione(schedule.Event): ciudad = models.ForeignKey( 'city_search.Città', on_delete=models.CASCADE, db_type='int' # 与Città.id的int类型保持一致 )
执行以下命令完成迁移:
# 生成新迁移文件 python manage.py makemigrations eventos # 执行迁移 python manage.py migrate eventos
方案2:升级Città模型的主键为BigAutoField(长期适配)
如果项目计划逐步统一使用Django 3.2+的默认主键类型,可升级Città的主键:
- 修改
city_search应用的Città模型:
class Città(models.Model): id = models.BigAutoField(primary_key=True) # 其他字段保持不变
- 生成并执行迁移(操作前请备份数据库):
python manage.py makemigrations city_search python manage.py migrate city_search
完成后,Manifestazione的外键会自动匹配BigAutoField类型,无需额外修改模型。
验证迁移配置
若怀疑迁移文件未生效,可打开eventos/migrations/下的最新迁移文件,查看ciudad_id字段的定义,确认其type是否为你指定的'int'(方案1)或'bigint'(方案2)。
内容的提问来源于stack exchange,提问作者H3x

