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

Django执行makemigrations重复生成同一迁移文件的问题求助

解决Django迁移重复生成与提示未同步问题

问题现象

  • 执行migrate命令时,反复收到模型未同步提示:

Your models in app(s): 'organization_app' have changes that are not yet reflected in a migration, and so won't be applied.
Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.

  • 执行makemigrations会重复生成针对PenaltyModel.tenant_penalty_choice字段的迁移文件,即便已完成migrate操作
  • 用sqlmigrate查看该迁移,输出为无实际操作的SQL:
BEGIN;
--
-- Alter field tenant_penalty_choice on penaltymodel
--
-- (no-op)
COMMIT;
  • 删除所有迁移文件重建后,问题依旧存在

问题根源

这不是Django的Bug,核心原因是Django迁移系统无法识别自定义枚举类生成的choices与迁移文件中硬编码选项的一致性。

你的模型中使用了TenantPenaltyChoices.choices动态引用枚举类选项,但生成的迁移文件里直接写死了choices=[("PERCENT", "Percent"), ("AMOUNT", "Amount")]静态列表。当Django对比模型定义与迁移记录时,会判定两者的choices来源不同,因此认为模型存在未同步的修改。

解决步骤

方法1:修改迁移文件使用枚举类引用(推荐)

编辑生成的迁移文件,将硬编码的choices替换为枚举类的直接引用:

# Generated by Django 4.2.3 on 2024-02-07 20:14
from django.db import migrations, models
# 导入你的枚举类
from organization_app.models import TenantPenaltyChoices


class Migration(migrations.Migration):
    dependencies = [
        ("organization_app", "0002_alter_penaltymodel_tenant_penalty_choice"),
    ]

    operations = [
        migrations.AlterField(
            model_name="penaltymodel",
            name="tenant_penalty_choice",
            field=models.CharField(
                choices=TenantPenaltyChoices.choices,
                default=TenantPenaltyChoices.AMOUNT,
                max_length=20,
            ),
        ),
    ]

执行migrate后,Django会判定模型与迁移的choices来源一致,不会再重复生成迁移。

方法2:模型中直接硬编码choices(不推荐)

若不想修改迁移文件,可将模型里的choices改为硬编码列表:

class PenaltyModel(models.Model):
    tenant_penalty_desc = models.TextField(null=False)
    tenant_penalty_name = models.CharField(max_length=100, null=False)
    tenant_penalty_percentage = models.IntegerField(default=0)
    tenant_penalty_amount = models.FloatField(default=0)
    tenant_penalty_choice = models.CharField(
        choices=[("PERCENT", "Percent"), ("AMOUNT", "Amount")],
        max_length=20,
        default="AMOUNT",
    )
    rental_house = models.OneToOneField(HouseModel, on_delete=models.CASCADE)

这种方式虽能解决问题,但会丢失枚举类的可维护性,仅适用于选项固定不变的场景。

方法3:彻底重置迁移状态(极端场景)

若前两种方法无效,可尝试重置迁移:

  1. 备份数据库(重要操作)
  2. 删除organization_app/migrations/目录下除__init__.py外的所有文件
  3. 删除数据库django_migrations表中所有属于organization_app的记录
  4. 执行python manage.py makemigrations organization_app生成全新初始迁移
  5. 执行python manage.py migrate --fake-initial organization_app标记初始迁移为已应用

注意:--fake-initial仅适用于数据库表已与当前模型结构一致的情况,使用前需确认结构匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 07:59:57