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

使用inspectdb后,如何迁移Django Rest中已修改的模型?

问题解决步骤

核心问题在于你跳过了「标记初始模型与数据库同步」的步骤,直接修改模型后生成的迁移会尝试创建已存在的表,导致冲突。按以下步骤操作即可解决:


1. 恢复初始模型状态

先把models.py改回和数据库中api_task表完全匹配的初始版本(也就是inspectdb生成的原始内容,注意默认会带managed=False,表示Django不管理表的创建):

class ApiTask(models.Model):
    task_id = models.AutoField(primary_key=True)
    task_title = models.CharField(max_length=15, blank=True, null=True)
    task_description = models.CharField(max_length=150, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'api_task'

2. 标记初始模型已同步

生成初始迁移文件,再告诉Django这个迁移对应的表已经在数据库里了,不用执行创建操作:

python manage.py makemigrations api
python manage.py migrate api --fake-initial

3. 修改模型为你需要的状态

这里要注意:如果要保留原有字段的数据,别直接改模型字段名,用db_column指定对应数据库的列名,避免数据丢失。示例:

class ApiTask(models.Model):
    task_id = models.AutoField(primary_key=True)
    # 用db_column映射到原数据库的task_title列,同时修改max_length
    title = models.CharField(max_length=100, blank=True, db_column='task_title')
    # 映射到原task_description列,改成TextField类型
    description = models.TextField(max_length=250, blank=True, db_column='task_description')
    # 添加新字段
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

    class Meta:
        db_table = 'api_task'
        managed = True  # 现在让Django管理表的修改

4. 生成并执行新迁移

这次生成的迁移只会包含字段属性修改和新字段添加的操作,不会重复创建表:

python manage.py makemigrations api
python manage.py migrate api

为什么之前的方法无效?

  • 直接修改模型后makemigrations,生成的迁移会尝试创建整个表,而数据库中表已存在,因此报错「relationship already exists」。
  • --fake只是让Django认为迁移已执行,但不会实际修改数据库的字段。
  • --run-syncdb仅适用于没有迁移文件的应用,你的api已经有迁移文件,所以无法使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 01:07:51