Django 1.8: 为现有模式创建初始迁移

我启动了一个 django 1.8项目,它使用迁移系统。
不知怎么的,事情变得一团糟,所以我从数据库中删除了迁移文件夹和表,现在我试图重建它们,但没有成功。

我有三个应用程序(3 models.py文件) ,和模型反映的表完全!

到目前为止,我找到的最好的方法是:

  1. 清除所有 migrations文件夹。完成!
  2. 删除 django_migrations表中的所有内容。完成!
  3. 对每个应用程序运行 python manage.py makemigrations --empty <app>,完成!
  4. 运行 python manage.py migrate --fake。完成! (虽然它只有当我在每个 makemigrations命令后运行它才能工作。

现在我添加一个新字段,运行 makemigrations命令,然后收到以下错误:
django.db.utils.OperationalError: (1054, "Unknown column 'accounts_plan.max_item_size' in 'field list'")

我已经在这上面浪费了好几个小时了。我该如何初始化迁移,以便每次都能在没有迁移中断的情况下继续工作?

为什么这么复杂? 为什么没有一个简单的一行程序: initiate_migrations_from_schema

编辑:
现在事情变得更糟糕了。我截断了 django_migrations表并删除了所有的 migrations文件夹。
现在我尝试运行 python manage.py migrate --fake-initial(我在 DEV 文档中找到的东西) ,这样它就可以设置 Django 的所有“内部”应用程序(auth、 session 等) ,我得到:
(1054, "Unknown column 'name' in 'django_content_type'").
现在,这个“专栏”不是一个真正的专栏。这是在 Django 的 contenttypes应用程序中定义的 @property。这是怎么回事?为什么它将 name属性标识为真正的列?

64915 次浏览

我遇到过这种情况,但我从来没有放弃数据库来解决它。通常我会从应用程序中删除迁移文件夹,并从数据库中删除迁移条目。

我会尝试一次运行一个应用程序进行迁移。如果任何应用程序依赖于其他表格,显然要最后添加它们。

而且我通常只是运行 Python management. py makhemations,然后只运行 Python management,即使是初始迁移,它也可以很好地与 Django 1.7和1.8一起工作。

终于让它工作了,虽然我不知道为什么,我希望它将在未来的工作。
在做了大量的试验和通过 Django 的开发站点(链接)。
下面是步骤(对于遇到这个问题的人) :

  1. 清空 django_migrations表: delete from django_migrations;
  2. 对于每个应用程序,删除其 migrations文件夹: rm -rf <app>/migrations/
  3. 重置“内置”应用程序的迁移: python manage.py migrate --fake
  4. 对于每个应用程序运行: python manage.py makemigrations <app>。照顾依赖关系(使用 ForeignKey 的模型应该在其父模型之后运行)。
  5. 最后: python manage.py migrate --fake-initial

之后,我运行了最后一个没有 --fake-initial标志的命令,只是为了确保。

现在一切正常,我可以正常使用迁移系统。

我相信我不是唯一一个遇到这个问题的人,它必须被更好地记录下来,甚至简化。

Django 1.9用户更新:
我用 Django 1.9.4再次进行了这个场景,步骤5失败了。
我所要做的就是用 --fake代替 --fake-initial使它工作。

如果你使用路由器,可能会有问题。检查方法 allow_migrate是否在 routers.py中以正确的方式执行。尝试设置返回值始终为 True,并检查它是否解决了问题,

def allow_migrate(self, db, app_label, model_name=None, **hints):
return True

姜戈... ,1.8,1.9,..。

您想要实现的是压缩现有的迁移并使用替换。

如何在不使用任何命令的情况下进行正确的发布(不影响数据库和同事的情况)。

  1. 对于每个应用程序,删除它的迁移文件夹: mv <app>/migrations/ <app>/migrationsOLD/

  2. 对于每个应用程序运行: python manage.py makemigrations <app>

  3. 自定义每个新的迁移:

    • 如果你有一个 复杂的应用程序,或更多的应用程序和相关的模型之间,以避免 CircularDependencyErrorValueError: Unhandled pending operations for models:

      <app> 0002_initial2.py中准备第二个空迁移(将依赖关系放在 app_other::0001_initial.py<app>: : 0001_initial.py上——所有 ForeignKey,M2M 都与在其他应用程序中的0001迁移步骤中创建的模型相关)

      一切都必须井井有条——有时候需要更多的迁徙来准备。在每次迁移中注意 dependencies属性。

    • 注意初始值-验证自己从 migrationsOLD的所有 RunPython动作,并复制代码到新的初始迁移,如果需要的话。

    • (对于 --fake-initial可选)将 initial=True添加到所有新的迁移类中(如果添加了,也添加0002)。

    • 在新的迁移类中添加 replaces属性。(比如自定义一个 squashmigrations)。将所有从 <app>迁移过来的旧属性放在那里
  4. makemigrations验证一切。

    断言“未检测到更改”

  5. 检查 migrate -l是否到处显示[ x ]

    断言类似:

    [ X ]0001 _ 首字母

    [ X ]0002 _ initial2(102次压缩迁移)

例如:

老年人:

0001_initial.py
0002_auto.py
...
0103_auto.py

预备:

0001_initial.py
0002_initial2.py  (optional but sometimes required to satisfy dependency)

并添加到 replaces到最后一个(这里是0002,可以是0001) :

replaces = [(b'<app>', '0002_auto.py'), ..., (b'<app>', '0103_auto.py')]

0001 _ initial.py 的命名方式应与旧的命名方式相同。

0002 _ initial2.py 是新的,但它是旧迁移的替代品,因此 Django 将其视为已加载。