Django中外键bigint与UUID类型不匹配,该如何解决?
问题
我在Django中将UUIDField设置为Organization模型的主键:
class Organization(models.Model): id = models.UUIDField(default=uuid.uuid4, primary_key=True, editable=False) name = models.CharField(max_length=124)
这部分功能正常,但在Member模型中使用Organization的id作为外键时:
class Member(models.Model): reference = models.ForeignKey('Organization', null=True, on_delete=models.PROTECT) name = models.CharField(max_length=124)
出现如下错误:
django.db.utils.ProgrammingError: column "reference" is of type bigint but expression is of type uuid LINE 1: "reference" = 'af104709-... ^ HINT: You will need to rewrite or cast the expression.
解决方法
场景1:未执行过数据库迁移(新项目/刚定义模型)
直接修改Member模型的外键定义,显式指定关联Organization的UUID主键,再重新生成并执行迁移:
class Member(models.Model): reference = models.ForeignKey( 'Organization', null=True, on_delete=models.PROTECT, to_field='id' # 明确关联UUID类型的主键 ) name = models.CharField(max_length=124)
执行迁移命令:
python manage.py makemigrations python manage.py migrate
场景2:已执行迁移,数据库中存在历史数据
这种情况需要先修改数据库字段类型,再同步模型定义:
- 生成空迁移文件:
python manage.py makemigrations your_app_name --empty
- 打开生成的迁移文件,添加字段类型修改逻辑(以PostgreSQL为例,其他数据库语法需对应调整):
from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ('your_app_name', '替换为之前的迁移文件名'), ] operations = [ # 先同步模型外键定义 migrations.AlterField( model_name='member', name='reference', field=models.ForeignKey(null=True, on_delete=models.PROTECT, to='Organization', to_field='id'), ), # 修改数据库字段类型为UUID migrations.RunSQL( "ALTER TABLE your_app_name_member ALTER COLUMN reference TYPE uuid USING reference::uuid;", ), ]
- 执行迁移:
python manage.py migrate
- 确保Member模型的外键定义和场景1中的代码一致,避免后续迁移异常。
错误原因
本质是:最初创建Member模型时,Django默认生成的外键字段为bigint类型(对应默认的AutoField主键),后续修改Organization主键为UUIDField后,数据库中的外键字段类型未同步更新,导致类型不匹配报错。
内容的提问来源于stack exchange,提问作者rahnama7m
相关产品推荐
相关产品推荐

