Django模型UUID主键字段未在PostgreSQL数据库中生成
Django迁移后PostgreSQL表缺失UUID主键字段的问题
在Kubernetes环境中运行Django应用,PostgreSQL作为独立服务部署。定义的Topic模型包含UUID类型主键key,生成的迁移文件也包含该字段,但执行迁移后,PostgreSQL的channels_topic表中始终缺失key字段,访问Topic对象时报错。
已完成排查:
- 确认应用连接目标数据库(通过Pod内环境变量,用psycopg2验证)
- 执行过
python manage.py flush; python manage.py migrate,甚至手动删除表后重新迁移,表重建但key字段仍未生成 - 通过psycopg2和pgadmin验证,表仅包含8个字段,而非模型定义的9个
- 无新建数据库权限,无法彻底重置数据库
模型代码
import uuid import datetime, pytz from django.db import models from django.conf import settings class Topic(models.Model): key = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) name = models.CharField(max_length=168) owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True) created = models.DateTimeField() updated = models.DateTimeField(default=datetime.datetime(2000, 1, 1, 0, 0, 0, 0, pytz.UTC)) keyword_json = models.TextField() model_bin = models.BinaryField() article_ttl = models.FloatField(default=48.0) timeliness = models.FloatField(defautl=4.0) # 注:此处存在拼写错误defautl -> default
迁移文件片段
name='Topic', fields=[ ('key', models.UUIDField(...)), ('name', models.CharField(...)), ('created', models.DateTimeField()), ('updated', models.DateTimeField(...)), ('keywords_json', models.TextField()), # 注:此处字段名keywords_json与模型中的keyword_json不一致 ('model_bin', models.BinaryField()), ('article_ttl', models.FloatField(...)), ('timeliness', models.FloatField(...)), ('owner', models.ForeignKey(...)) ]
数据库表结构查询结果
# 在Django服务Pod中执行python manage.py shell >>> import os >>> import psycopg2 >>> conn = psycopg2.connect(dbname=os.environ['POSTGRES_DB'], user=...rest from os.environ...) >>> curr = conn.cursor() >>> curr.execute("""SELECT column_name, data_type, character_maximum_length, column_default, is_nullable FROM information_schema.columns WHERE table_name='channels_topic';""") >>> res = list(curr) >>> res [('name', 'character_varying', 168, None, 'NO'), ('created', 'timestamp with time zone', None, None, 'NO'), ('updated', 'timestamp with time zone', None, None, 'NO'), ('keyword_json', 'text', None, None, 'NO'), ('model_bin', 'bytea', None, None, 'NO'), ('article_ttl', 'double precision', None, None, 'NO'), ('timeliness', 'double precision', None, None, 'NO'), ('owner_id', 'integer', None, None, 'YES') ]
解决方案
1. 修正模型拼写错误
先修复timeliness字段的参数拼写错误:将defautl=4.0改为default=4.0。该错误可能导致Django处理模型时出现异常,干扰迁移执行逻辑。
2. 同步迁移文件与模型字段名
迁移文件中keywords_json字段名和模型里的keyword_json不一致(多了一个s),说明迁移文件未匹配当前模型。需删除对应Topic模型的旧迁移文件,重新生成:
- 备份现有迁移文件(避免丢失历史记录)
- 删除
channels应用下与Topic相关的迁移文件(如000x_xxxx.py) - 执行
python manage.py makemigrations生成新迁移文件,确认文件中key字段存在且字段名与模型完全一致
3. 强制执行迁移并修正历史标记
执行python manage.py migrate --fake-initial,跳过已标记为应用的初始迁移,强制应用新生成的迁移文件,确保字段被正确创建。
4. 手动添加字段(应急方案)
若上述方法无效,直接在数据库中手动添加字段:
ALTER TABLE channels_topic ADD COLUMN key UUID PRIMARY KEY DEFAULT gen_random_uuid();
然后更新Django迁移历史,标记该字段的迁移已完成:
# 在Django shell中执行 from django.db import connection cursor = connection.cursor() # 替换为你的新迁移文件名称,例如channels.0003_add_key_field cursor.execute("INSERT INTO django_migrations (app, name, applied) VALUES ('channels', '0003_add_key_field', now());")
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

