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

Django+Postgres使用UUID做主键报bigint类型不匹配错误

问题解答

报错根本原因

你最初创建Book模型时未显式指定主键,Django默认生成了bigint类型的自增id字段作为主键,且你已经执行过迁移在PostgreSQL中创建了对应表结构。后续你直接修改模型将id调整为UUIDField类型,但Django默认迁移工具无法自动完成「已有bigint主键转UUID主键」的字段类型变更,导致数据库中表的id字段实际仍为bigint类型,ORM操作时按照模型定义传入UUID值,就触发了类型不匹配的报错。

更简便的解决方法

表内无需要保留的业务数据

无需删除整个应用,仅重置对应应用的Book模型相关迁移即可:

  • 删除该应用migrations目录下除__init__.py外的所有迁移文件
  • 进入PostgreSQL执行SQL删除对应表:DROP TABLE IF EXISTS 你的应用名_book;
  • 删除django_migrations表中该应用对应的迁移记录:DELETE FROM django_migrations WHERE app='你的应用名';
  • 重新生成并执行迁移:
python manage.py makemigrations
python manage.py migrate

该方案仅调整出问题的模型相关配置,不需要修改其他业务代码、也无需重建整个应用。

表内有需要保留的业务数据

需要手动编写迁移完成字段类型转换,步骤如下:

  1. 先在Book模型中新增临时UUID字段:
temp_id = models.UUIDField(default=uuid.uuid4, unique=True, null=True)

生成并执行一次迁移,为现有所有数据自动填充UUID值。
2. 手动创建空迁移文件:

python manage.py makemigrations 你的应用名 --empty
  1. 编辑新生成的空迁移文件,添加主键切换的SQL操作:
from django.db import migrations

class Migration(migrations.Migration):
    dependencies = [
        ('你的应用名', '上一步生成的迁移文件的前缀名'),
    ]

    operations = [
        migrations.RunSQL(
            """
            ALTER TABLE 你的应用名_book DROP CONSTRAINT 你的应用名_book_pkey;
            ALTER TABLE 你的应用名_book RENAME COLUMN id TO old_id;
            ALTER TABLE 你的应用名_book RENAME COLUMN temp_id TO id;
            ALTER TABLE 你的应用名_book ADD PRIMARY KEY (id);
            """
        )
    ]
  1. 执行迁移后,将Book模型中的临时temp_id字段和旧的主键定义删除,换回你当前使用的UUID类型id字段定义,再次生成并执行迁移即可。不需要保留旧id数据的话,可以额外执行SQL删除old_id字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 23:27:03