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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 03:07:05