我启动了一个Django1.8项目,它使用迁移系统。不知怎么的,事情变得一团糟,所以我从数据库中删除了迁移文件夹和表,现在我正试图重建它们,但没有成功。
我有三个应用程序(3个models.py文件),模型完全反映了表格!
到目前为止,我发现最好的方法是:
清除所有migrations文件夹。完成!
从django_migrations表中删除所有内容。完成!
为每个应用程序运行python manage.py makemigrations --empty 。完成!
运行python manage.py migrate --fake。完成!(尽管只有在每次执行makemigrations命令后才运行它。
现在我添加了一个新字段,运行makemigrations命令,收到以下错误:django.db.utils.OperationalError: (1054,"Unknown column 'accounts_plan.max_item_size' in 'field list'")
我在这件事上忙了好几个小时。H**L如何初始化迁移,以便每次都能在不中断迁移的情况下继续工作?
为什么这么复杂?为什么没有一个简单的一行: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属性标识为实列?
- 您删除了实际表吗?或者你只是清空了它?
- 我刚把它倒空了:delete from django_migrations。
- 你可能需要放下所有的桌子,而不仅仅是清空它们
- 我在这些表中有数据,不想删除它们。我知道我可以备份、删除、创建和恢复数据。但我有10张桌子,我不想这样做。我只想开始迁移。
最后终于成功了,虽然我不知道为什么,我希望它能在未来发挥作用。在做了大量的试验并通过Django的dev站点(link)之后。以下是步骤(对于遇到此问题的人):
清空django_migrations表:delete from django_migrations;。
对于每个应用程序,删除其migrations文件夹:rm -rf /migrations/。
重置"内置"应用程序的迁移:python manage.py migrate --fake。
对于每个应用程序运行:python manage.py makemigrations 。注意依赖性(具有foreignkey的模型应该在其父模型之后运行)。
最后:python manage.py migrate --fake-initial。
在那之后,我运行了最后一个没有--fake-initial标志的命令,只是为了确保。
现在一切正常,我可以正常使用迁移系统。
我相信我不是唯一一个遇到这个问题的人。它必须被更好地记录,甚至简化。
Django 1.9用户更新:我用django 1.9.4再次遇到了这种情况,第5步失败了。我所要做的就是用--fake替换--fake-initial,使其正常工作。
- 不过,我正在为django 1.8.3做最后一步。你知道为什么吗?
- @埃里克试着在最后一步之前运行python manage.py migrate contenttypes。
- 0.o……成功了!
- 应记录在"如何重置迁移"下。甚至可能是重置迁移管理命令
- 谢谢你,我在别的地方找不到怎么做…这确实应该记录下来。
- 必须从django_迁移中删除,然后运行python manage.py migrate。它奏效了。
- 如果从根目录运行,find . -path *migrations* -name"*.py" -not -path"*__init__*" -delete将删除所有迁移文件。为了安全起见,先运行find . -path *migrations* -name"*.py" -not -path"*__init__*"。
- 我在Pydanny Cookiecutter Django的项目上取得了成功(谢谢)。但是,对于生成的myproject/contrib/sites有一些技巧(我不太了解)。如果没有迁移/在myproject/contrib/sites中,我无法运行步骤3(migrate fake)。因此,我建议:步骤2:重命名迁移->migod,步骤3b:还原migod->迁移,其中步骤3失败并再次运行3,步骤3c:重复步骤1(再次删除django迁移内容),步骤3d:重复步骤2(其中应用了步骤3b)。….resetmigations会很棒的!
- 另外,我不确定为外部应用程序"重置迁移"是否是个好主意(比如Django本身:auth,…)。他们升级后的版本会发生什么?如果我们想为自己的应用程序做这件事,那么我们可以在步骤3(迁移假应用程序)期间临时将它们从已安装的应用程序中删除。可能在urls.py中有一些来自自己应用程序的导入,步骤3将失败。(所以我临时删除了urls.py中的所有内容。但是,必须至少定义一个URL)。因此,我们可以"重置迁移",让django+第三方不做任何更改。
- 当然,稍后其他数据库实例也会出现问题。这意味着也导入了sqldata/fixture(稍后必须从最终状态重新创建它们)。我这样做:1)git checkout,2)。/manage.py migrate我们有最后一个状态,3)git checkout,4)从django_migrations删除;4)。/manage.py migrate--假
Django…,1.8,1.9,…
您要实现的是压缩现有的迁移并使用替换。
如何在发布时不使用任何命令(对数据库和同事没有影响的情况)而正确地执行它。
对于每个应用程序,去掉迁移文件夹:mv /migrations/ /migrationsOLD/
对于每个应用程序运行:python manage.py makemigrations 。
自定义每个新迁移:
如果您有一个复杂的应用程序,或多个应用程序和它们之间的相关模型,以避免CircularDependencyError或ValueError: Unhandled pending operations for models:
在0002_initial2.py中准备第二次空移植(对app_other::0001_initial.py和的依赖关系:0001_initial.py以及所有foreignkey、M2M,与其他应用程序在0001移植步骤中创建的模型相关)
一切都必须井然有序——有时需要更多的迁移来准备。在每次迁移中都要注意这里的dependencies属性。
注意初始值-验证来自migrationsOLD的所有RunPython操作,并在需要时将代码复制到新的初始迁移。
(对于--fake-initial可选)将initial=True添加到所有新的迁移类(如果添加了,也添加了0002)。
- 在新的迁移类中添加replaces属性。(就像自己的习俗一样,一个江户一〔28〕)。把所有来自江户的旧移民都放在那里。
用makemigrations验证所有内容。
断言"未检测到更改"
检查migrate -l是否到处显示[x]
断言相似:
[X]0001_首字母
[X]0002_首字母2(102次挤压迁移)
例子:
老年人:
1 2 3 4
| 0001_initial.py
0002_auto.py
...
0103_auto.py |
准备:
1 2
| 0001_initial.py
0002_initial2.py (optional but sometimes required to satisfy dependency) |
在replaces中加上最后一个(这里的0002,可以是0001):
1
| replaces = [(b'', '0002_auto.py'), ..., (b'', '0103_auto.py')] |
0001_initial.py的命名方式应与旧的相同。
0002.py是新的,但它是旧迁移的替代品,因此Django会将其视为已加载。
我遇到过这种情况,但我从来没有必要删除数据库来解决它。通常,我会从应用程序中删除migration s文件夹,然后从数据库中删除迁移条目。
我会尝试一次运行一个应用程序进行迁移。如果应用程序的任何一个依赖于其他表,那么显然最后添加它们。
另外,我通常只运行python manage.py makemigrations,然后只运行python manage.py migrate,即使在初始迁移时,它也可以与django 1.7和1.8一起工作。
- 尝试过,但显然不起作用,因为migrate命令试图创建表(已经存在)。
- 你能试试>>python makemigrations yourapp——初始
- 试过了,得到:manage.py makemigrations: error: unrecognized arguments: --initial。
如果您使用路由器,可能存在问题。检查方法allow_migrate是否在routers.py中正确执行。尽量将返回值设置为True,检查是否能解决问题。
1 2
| def allow_migrate(self, db, app_label, model_name=None, **hints):
return True |
谢谢-我已经研究这个问题一段时间了,你的最佳实践列表真的很方便。这可能有助于像我这样的Python新手:
如果您从现有的一组模型开始,请清除以前进行的任何迁移!
我的情况是,我开始使用sqlite只是为了了解django,然后切换到一个mysql数据库-它不断抛出1053错误,可能试图应用以前的迁移,它没有解决的资源…