使用Django/DRF创建CRUD API时,Postgres RandomUUID作为主键默认值迁移报错问题
嗨,我来帮你搞定这个迁移报错的问题!
你碰到的这个错误,核心原因是Django的迁移系统没办法确认你传入的RandomUUID(直接传了类本身)在迁移过程中能生成唯一值——毕竟RandomUUID是封装PostgreSQL数据库函数的工具类,不是Python本地能直接生成唯一值的可调用对象,Django在生成迁移文件时,没法提前验证这个数据库函数的唯一性,所以抛出了这个警告。而且你直接传RandomUUID类而不是它的实例,也不符合数据库函数默认值的正确用法。
刚好你想要的就是让PostgreSQL自己生成UUID、完全不用Python的uuid模块,那正确的做法是用db_default参数(而非default)来指定数据库层面的默认值,这样Django就会把默认值的生成逻辑彻底交给数据库处理。
给你两种可行的修改方案:
方案一:用Django封装的RandomUUID数据库函数
修改模型代码,把default换成db_default,并传入RandomUUID()实例:
from django.db import models from django.contrib.postgres.functions import RandomUUID class Year(models.Model): year_id = models.UUIDField( primary_key=True, db_default=RandomUUID(), # 实例化RandomUUID,指定数据库端默认值 editable=False )
方案二:直接用PostgreSQL原生的UUID生成函数
如果你更倾向于用PostgreSQL原生的uuid_generate_v4()函数,也可以这么写:
from django.db import models class Year(models.Model): year_id = models.UUIDField( primary_key=True, db_default='uuid_generate_v4()', # 直接指定数据库原生函数 editable=False )
不过用这个方案的话,要先确保你的PostgreSQL数据库启用了uuid-ossp扩展——你可以创建一个空迁移文件,在里面执行CREATE EXTENSION IF NOT EXISTS "uuid-ossp";,或者手动在数据库里运行这条SQL语句。
修改完模型后,记得先删掉之前生成的错误迁移文件,再重新运行:
python manage.py makemigrations python manage.py migrate
这样就能完美实现你想要的效果:由PostgreSQL负责生成UUID主键,完全不需要Python的uuid模块参与。
备注:内容来源于stack exchange,提问作者user3125823

