连续执行两次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'
问题分析与解决
重复生成迁移的原因:
第二个迁移文件中ForeignObject的to_fields参数存在语法错误——("id" "date")缺失逗号,应为("id", "date")。Django迁移检测机制因语法错误无法正确识别字段定义的一致性,因此重复生成了迁移文件。执行报错的原因:
to_fields的语法错误导致Django处理迁移时无法正确解析字段关联信息,最终传递给数据库操作的name参数为None,触发startswith调用异常。解决步骤:
- 删除自动生成的第二个迁移文件(0005_alter_foo.py);
- 修正模型中
ForeignObject字段的to_fields参数,确保用逗号分隔:to_fields=("id", "date"); - 重新执行
makemigrations,此时第二次执行不会再生成多余迁移; - 执行
migrate完成数据库迁移。
内容的提问来源于stack exchange,提问作者ben w
相关产品推荐
相关产品推荐

