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

连续执行两次Django makemigrations生成无效迁移并报错问题

Django迁移异常:重复生成迁移文件且执行报错None.startswith

问题现象

连续执行两次makemigrations命令,第二次本应无任何操作,却生成了第二个迁移文件,且该迁移无法应用,触发AttributeError: 'NoneType' object has no attribute 'startswith'异常。

命令执行输出:

% ./manage.py makemigrations                                                                 
Migrations for 'foo':
  foo/migrations/0004_foo.py
    - Add field foo to bar
% ./manage.py makemigrations
Migrations for 'foo':
  fooo/migrations/0005_alter_foo.py
    - Alter field foo on bar

迁移文件内容

第一个迁移文件(0004_foo.py)

operations = [
    migrations.AddField(
        model_name="bar",
        name="foo",
        field=models.ForeignObject(
            default=1,
            from_fields=["original_id", "original_date"],
            on_delete=django.db.models.deletion.PROTECT,
            related_name="+",
            to="foo.baz",
            to_fields=["id", "date"],
        ),
        preserve_default=False,
    ),
]

第二个迁移文件(0005_alter_foo.py)

operations = [
    migrations.AlterField(
        model_name="bar",
        name="foo",
        field=models.ForeignObject(
            from_fields=("original_id", "original_date"),
            on_delete=django.db.models.deletion.PROTECT,
            related_name="+",
            to="payment.payment",
            to_fields=("id" "date"),  # 语法错误:缺失逗号
        ),
    ),
]

执行迁移时的报错

File "/Users/wolfson/.local/share/virtualenvs/message_digest-gQFszokA/lib/python3.11/site-packages/django/db/backends/postgresql/operations.py", line 189, in quote_name
    if name.startswith('"') and name.endswith('"'):                                                                                                            
       ^^^^^^^^^^^^^^^                                
AttributeError: 'NoneType' object has no attribute 'startswith'

问题分析与解决

  1. 重复生成迁移的原因:
    第二个迁移文件中ForeignObject的to_fields参数存在语法错误——("id" "date")缺失逗号,应为("id", "date")。Django迁移检测机制因语法错误无法正确识别字段定义的一致性,因此重复生成了迁移文件。

  2. 执行报错的原因:
    to_fields的语法错误导致Django处理迁移时无法正确解析字段关联信息,最终传递给数据库操作的name参数为None,触发startswith调用异常。

  3. 解决步骤:

    • 删除自动生成的第二个迁移文件(0005_alter_foo.py);
    • 修正模型中ForeignObject字段的to_fields参数,确保用逗号分隔:to_fields=("id", "date");
    • 重新执行makemigrations,此时第二次执行不会再生成多余迁移;
    • 执行migrate完成数据库迁移。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 07:34:52