Python Django 1.7 迁移不会重新创建删除的表,为什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26713231/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Django 1.7 migrations won't recreate a dropped table, why?
提问by Prometheus
Using Django 1.7 migrations.
使用 Django 1.7 迁移。
I accidentally dropped a table in my database. I assumed that by running migration again this would recreate the table but no, Django states "No migrations to apply".
我不小心在我的数据库中删除了一个表。我认为通过再次运行迁移,这将重新创建表,但没有,Django 声明“没有应用迁移”。
How to I get Django to recreate the table?
如何让 Django 重新创建表?
I have run:
我跑了:
> makemigrations - No changes detected
> migrate - No migrations to apply.
I have tried making a change to the model and running a new migration and it simply states that "Table 'x.test_customer' doesn't exist" which is correct, but what I was hoping it that it would recreate the table.
我尝试对模型进行更改并运行新的迁移,它只是指出“表 'x.test_customer' 不存在”,这是正确的,但我希望它能重新创建表。
采纳答案by yuvi
Migrations check for differences in your models, then translates that to actions, which are translated to SQL. It does notautomatically sync the db scheme with your models, and it has no way of knowing you dropped a table (it doesn't know about manual changes because, well, you're not supposed to do manual changes. That's the point)
迁移检查模型中的差异,然后将其转换为操作,然后再转换为 SQL。它不会自动将数据库方案与您的模型同步,并且无法知道您删除了表(它不知道手动更改,因为您不应该进行手动更改。这就是重点)
The answer? a manual change requires a manual migration as well. What you need to do is simply write your own migration and manually tell south to re-build the table. It's not very difficult, The docsmake it pretty easy. Just make something like this:
答案?手动更改也需要手动迁移。您需要做的就是简单地编写自己的迁移并手动告诉南重新构建表。这不是很困难,文档使它很容易。做这样的事情:
from django.db import migrations, models
class Migration(migrations.Migration):
operations = [
migrations.CreateModel("Foo"),
migrations.AddField("Foo", "bar", models.IntegerField(default=0))
]
You can probably look into the first migration file (the one that made the model in the first place) and copy paste almost all of it. Then all you have to do is run the migration like you always do
您可能可以查看第一个迁移文件(首先创建模型的文件)并复制粘贴几乎所有文件。然后你所要做的就是像往常一样运行迁移
回答by johannestaas
I actually found an easier way to do this. You fake that you rollback what doesn't exist, then you re-migrate. If your migration 0005 was the one where it creates the table:
我实际上找到了一种更简单的方法来做到这一点。您假装回滚不存在的内容,然后重新迁移。如果您的迁移 0005 是它创建表的地方:
python manage.py migrate myapp --fake 0004
python manage.py migrate myapp
Should be good after that!
之后应该就好了!
If you need to skip later ones, you do this:
如果你需要跳过后面的,你可以这样做:
python manage.py migrate myapp --fake 0004
python manage.py migrate myapp 0005
python manage.py migrate myapp --fake
Should be good after that!
之后应该就好了!
回答by JL Peyret
OK, so what I did was not to mess with migrations. Seems like I get in trouble every so often with migrations. And in this case, trying to replay migrations got me nowhere. Might not have helped that there were some South-vintage migrations as well as the newer 1.7 stuff.
好的,所以我所做的不是搞乱迁移。似乎我经常在迁移时遇到麻烦。在这种情况下,尝试重放迁移让我无处可去。可能没有帮助,有一些南方复古迁移以及更新的 1.7 东西。
environment: postgres 9.3
环境:postgres 9.3
Basically, I restored an old backup of my database into an empty database. Then I brought up the restore target in the postgres admin utility and copy/pasted the create tables from each table's description (I had only 4 to go). Switched over to my test database & ran it in pg's sql utility.
基本上,我将数据库的旧备份恢复到空数据库中。然后我在 postgres 管理实用程序中调出恢复目标,并从每个表的描述中复制/粘贴创建表(我只有 4 个)。切换到我的测试数据库并在 pg 的 sql 实用程序中运行它。
I dunno, I don't think it is unreasonable to drop a table manually if you are having issues with it (looked to me as if my id field's sequence was not working), as long as you can live with losing your data. Migrations should be resilient in that use case.
我不知道,如果您遇到问题(在我看来,好像我的 id 字段的序列不起作用),我不认为手动删除表是不合理的,只要您能忍受丢失数据。在该用例中,迁移应该具有弹性。
回答by kunl
Full disclaimer, this is a destructive operation in some cases, and I mostly use it to remigrate parts of the system without affecting the DB.
完全免责声明,这在某些情况下是一种破坏性操作,我主要用它来重新迁移系统的某些部分而不影响数据库。
Have you tried doing it via the table django_migrations? Just remove the rows that map to the app label and the migration names in question and delete those rows.
你有没有试过通过桌子来做django_migrations?只需删除映射到应用程序标签和相关迁移名称的行,然后删除这些行。
+----+-----------------------+----------------------------------------------------------+---------------------+
| id | app | name | applied |
+----+-----------------------+----------------------------------------------------------+---------------------+
| 1 | contenttypes | 0001_initial | 2015-03-07 16:32 |
| 30 | homepage | 0001_initial | 2015-04-02 13:30:44 |
| 31 | homepage | 0002_auto_20150408_1751 | 2015-04-08 12:24:55 |
| 32 | homepage | 0003_remove_mappinghomepagemoduleinventory_inventoryinfo | 2015-04-09 08:09:59 |
+----+-----------------------+----------------------------------------------------------+---------------------+
So now if i want to remove homepage, I can just delete row 30, 31, 32.
所以现在如果我想删除homepage,我可以删除第 30、31、32 行。
Of course since you dropped the tables too, you'd need to change django_content_typetoo:
当然,由于您也删除了表,因此您也需要更改django_content_type:
+----+----------------------------------------+-----------------------+--------------------------------------+
| id | name | app_label | model |
+----+----------------------------------------+-----------------------+--------------------------------------+
| 1 | content type | contenttypes | contenttype |
| 2 | session | sessions | session |
| 3 | site | sites | site |
| 92 | master_homepagemodule_extrafields | homepage | masterhomepagemoduleextrafields |
| 93 | mapping_homepagemodule_inventory | homepage | mappinghomepagemoduleinventory |
| 94 | master_homepagemodule_inventoryfields | homepage | masterhomepagemoduleinventoryfields |
| 95 | mapping_homepagemodule_inventoryfields | homepage | mappinghomepagemoduleinventoryfields |
| 96 | master_homepagemodule | homepage | masterhomepagemodule |
| 97 | mapping_homepagemodule_extrafields | homepage | mappinghomepagemoduleextrafields |
+----+----------------------------------------+-----------------------+--------------------------------------+
So now you'd have to remove the tables that you need to remigrate need by dropping the rows for those tables.
因此,现在您必须通过删除这些表的行来删除需要重新迁移的表。
I've used this when time was scarce and we needed a quick dirty fix, or when playing around in development.
Hope it helps you too!
我在时间有限并且需要快速修复或在开发过程中使用它时使用它。
希望对你也有帮助!
回答by J.Q
Go to your database and find the table django_migrations. Delete all the rows which have appequals your app name.
转到您的数据库并找到该表django_migrations。删除所有app等于您的应用程序名称的行。
Then do a makemigrations& migratewill work.
然后做一个makemigrations&migrate将工作。
回答by Raúl EL
Another solution I've found and works perfectly:
我发现并完美运行的另一个解决方案:
In django 1.7:
在 Django 1.7 中:
Delete your migrations folder
In the database:
DELETE FROM django_migrations WHERE app = 'app_name'.You could alternatively just truncate this table.
python manage.py makemigrationspython manage.py migrate --fake
删除您的迁移文件夹
在数据库中:
DELETE FROM django_migrations WHERE app = 'app_name'.您也可以只截断此表。
python manage.py makemigrationspython manage.py migrate --fake
In django 1.9.5:
在 Django 1.9.5 中:
- Delete your migrations folder
In the database:
DELETE FROM django_migrations WHERE app = 'app_name'.You could alternatively just truncate this table.
python manage.py makemigrations app_namepython manage.py migrate
- 删除您的迁移文件夹
在数据库中:
DELETE FROM django_migrations WHERE app = 'app_name'.您也可以只截断此表。
python manage.py makemigrations app_namepython manage.py migrate
This works 100% for me!
这对我来说 100% 有效!
回答by yekta
The simplest way to do this on django >= 1.9 is to run the following:
在 django >= 1.9 上执行此操作的最简单方法是运行以下命令:
./manage.py migrate app_name zero
That will remove your tables and revert all migrations.
这将删除您的表并恢复所有迁移。
回答by SirSaleh
In my case in django 2.0.2for recreating dropped table I needed to comment my models in myappand then migrate with --fakeand uncomment my models and migrate without --fakeA little different from raul answer:
在我的情况下,django 2.0.2为了重新创建删除的表,我需要在其中注释我的模型myapp,然后使用--fake和取消注释我的模型并
在没有与 raul 答案有点不同的情况下--fake迁移:
- Delete your migrations files in your desired app
- Thanks to raul answer: In the database:
DELETE FROM django_migrations WHERE app = 'app_name'. - comment codes in
models.pyand all this models usage inviews,signalsand etc (to prevent error). python manage.py makemigrations YOUR_APP_NAMEpython manage.py migrate --fake- un-comment what you commented in step 3
python manage.py makemigrations YOUR_APP_NAME- migrate without --fake:
python manage.py migrate
- 删除所需应用程序中的迁移文件
- 感谢劳尔回答:在数据库中:
DELETE FROM django_migrations WHERE app = 'app_name'。 - 中的注释代码
models.py和所有这些模型的用法views,signals等等(以防止错误)。 python manage.py makemigrations YOUR_APP_NAMEpython manage.py migrate --fake- 取消评论您在第 3 步中评论的内容
python manage.py makemigrations YOUR_APP_NAME- 不带 --fake迁移:
python manage.py migrate
This should solve some users problem.
这应该可以解决一些用户问题。
回答by techbrownbags
Just ran into this while building a little app learning django. I wanted to create a non-null column for an existing table. There were three steps:
在构建一个学习 django 的小应用程序时遇到了这个问题。我想为现有表创建一个非空列。共有三个步骤:
- drop the table
- remove the record in django_migrations
- remove the migration for the table in question
- if you run "python manage.py makemigrations posts" before this step you still get the "You are trying to add a non-nullable field "
- 放下桌子
- 删除 django_migrations 中的记录
- 删除相关表的迁移
- 如果您在此步骤之前运行“python manage.py makemigrations posts”,您仍然会收到“您正在尝试添加不可为空的字段”
For an actual application you'd need to supply a default value as others have pointed out.
对于实际应用程序,您需要提供其他人指出的默认值。

