Django从2.1升级到2.2时出现psycopg2唯一约束冲突错误求助
解决Django 2.1升级到2.2后数据库迁移的唯一约束冲突问题
问题根源
你之前为修复代理模型权限问题手动添加了自定义命令,生成了重复的权限记录;而Django 2.2原生修复了代理模型权限逻辑,迁移时会自动创建标准权限,导致auth_permission表的(content_type_id, codename)唯一约束冲突。
解决步骤(全程确保数据库已备份)
1. 确认重复的权限记录
先通过Django Shell定位重复条目:
python manage.py shell
在Shell中执行:
from django.contrib.auth.models import Permission from django.contrib.contenttypes.models import ContentType # 定位冲突的内容类型 ct = ContentType.objects.get(id=114) # 查询重复的权限 duplicate_perms = Permission.objects.filter(content_type=ct, codename='add_djangouser') # 输出重复记录的ID和名称,方便区分 for perm in duplicate_perms: print(f"权限ID: {perm.id}, 名称: {perm.name}")
2. 备份数据库(必须先做)
用PostgreSQL命令备份当前数据库,防止数据丢失:
pg_dump -U 你的数据库用户名 数据库名称 > django_upgrade_backup.sql
3. 删除重复的权限记录
根据Shell查询结果,保留Django 2.2迁移要生成的标准权限(通常是较新的ID,或名称更规范的那条),删除自定义命令生成的旧权限:
# 假设要保留的权限ID是1234,替换成你实际的ID keep_perm_id = 1234 duplicate_perms.exclude(id=keep_perm_id).delete()
4. 执行数据库迁移
处理完重复数据后,重新执行迁移:
python manage.py migrate
如果仍有冲突,可先标记冲突的auth迁移为已执行(替换成实际的迁移编号,比如0012_xxx):
python manage.py migrate --fake auth 0012_xxx
再重新执行完整迁移。
5. 清理自定义权限相关代码
- 删除之前为修复代理模型权限编写的自定义命令文件。
- 检查项目中是否有调用该自定义命令的脚本或逻辑,一并清理。
6. 验证权限正确性
- 登录Admin后台,检查代理模型的权限是否正常显示。
- 再次通过Shell查询代理模型的权限,确认无重复且符合预期:
# 替换成你的代理模型类 from yourapp.models import DjangoUserProxy ct = ContentType.objects.get_for_model(DjangoUserProxy) perms = Permission.objects.filter(content_type=ct) print([perm.codename for perm in perms])
内容的提问来源于stack exchange,提问作者M.N
相关产品推荐
相关产品推荐

