Django Migration未应用迁移更改

时间:2015-04-27 17:33:29

标签: django

使用django 1.7.7我想使用django的迁移来添加或删除字段。 所以我修改了model.py并运行了

python manage.py makemigrations myproj
Migrations for 'myproj':
  0001_initial.py:
    - Create model Interp
    - Create model InterpVersion

python manage.py migrate myproj
Operations to perform:
  Apply all migrations: myproj
Running migrations:
  Applying myproj.0001_initial... FAKED

python manage.py runserver

然后检查管理页面,它没有更新。 然后我尝试删除迁移文件夹并再次尝试; migrate命令表示没有要应用的迁移。

我该如何进行迁移? 注意:我想使用django迁移的新技术而不是旧的南方法。

8 个答案:

答案 0 :(得分:18)

删除迁移目录永远不是一个好主意,因为Django然后失去了已经应用了哪些迁移以及哪些迁移不被追踪(并且一旦将应用部署到某个地方,就很难让事情恢复同步)。

  

免责声明:无论何时发生这种情况,最好备份数据库,如果它包含任何有价值的内容。如果在早期开发中没有必要,但是一旦后端的事情变得不同步,事情就有可能变得更糟。 : - )

要恢复,您可以尝试重置模型 ,以便在添加/删除字段之前完全匹配 。然后你可以运行

$ python manage.py makemigrations myproj

将导致初始迁移(0001_initial...)。然后你可以告诉Django伪造那个迁移,这意味着告诉它设置它的内部计数器0001_initial

使用Django 1.7:

$ python manage.py migrate myproj

使用Django> = 1.8:

$ python manage.py migrate myproj --fake-initial

现在,尝试更改模型并再次运行makemigrations。它现在应该创建一个0002_foobar迁移,您可以按预期运行。

答案 1 :(得分:11)

确保migrations/文件夹包含__init__.py文件

超过半小时。

答案 2 :(得分:6)

就我而言,迁移没有反映在mysql数据库中。我从表格中手动删除了' myapp'(在您的情况下' myproj')' django_migrations'在mysql数据库中,再次运行相同的命令进行迁移。

答案 3 :(得分:1)

除了其他答案之外,请确保在models.py中,每个表的元数据中都有managed = True

答案 4 :(得分:0)

我发现Django迁移有点神秘,而且往往更喜欢外部工具(例如liquibase)。

但是,我刚刚遇到了“无需迁移”问题。我也尝试删除migrations文件夹,但没有帮助。

如果你已经删除了migrations文件夹,这里的方法对我有用。

首先,生成新的“干净”迁移:

$ python manage.py makemigrations foo
Migrations for 'foo':
  dashboard/foo/migrations/0001_initial.py
    - Create model Foo
    - Create model Bar

然后查看SQL并查看它是否合理:

$ python manage.py sqlmigrate foo 0001
BEGIN;
--
-- Create model Foo
--
CREATE TABLE "foo" ("id" serial NOT NULL PRIMARY KEY, ... "created_at" timestamp with time zone NOT NULL, "updated_at" timestamp with time zone NOT NULL);
CREATE INDEX "..." ON "foo" (...);
COMMIT;

然后在您的数据库上应用相同的SQL。

我正在使用Postgres,但它与其他引擎类似。

一种方法是将内容写入文件:

$ python manage.py sqlmigrate foo 0001 > foo.sql
$ psql dbname username < foo.sql
BEGIN
CREATE TABLE
CREATE INDEX
COMMIT

另一个是直接管道SQL:

$ python manage.py sqlmigrate foo 0001 | psql dbname username

或复制并粘贴等等。

答案 5 :(得分:0)

以上大多数解决方案都可以解决该问题,但是,我想指出另一种可能(尽管很少见)的可能性,即数据库路由器的allow_migrate方法可能在应该返回False的情况下已返回None

Django具有设置DATABASE_ROUTERS,该设置将用于确定执行数据库查询时使用哪个数据库。

从文档中

  

如果要实现更有趣的数据库分配行为,则可以定义并安装自己的数据库路由器。

数据库路由器类最多实现四个方法:

  • db_for_read(model,**提示)
  • db_for_write(模型,**提示)
  • allow_relation(obj1,obj2,**提示)
  • allow_migrate(db,app_label,model_name = None,**提示)

来自documentation

  

allow_migrate(db,app_label,model_name = None,**提示)

     

确定是否允许在别名为db的数据库上运行迁移操作。如果该操作应该运行,则返回True;否则,则返回False;如果路由器没有意见,则返回None。

可能有一个顺序的数据库路由器正在为您要运行的迁移返回 False ,在这种情况下,该特定操作将不会运行。

答案 6 :(得分:0)

pip install django-extensions

并在安装应用中添加它

INSTALLED_APPS = [
    'django_extensions'
]
python ./manage.py reset_db

python manage.py makemigrations
python manage.py migrtate

现在安装您的应用程序

python manage.py makemigrations your_app_name
python manage.py migrtate your_app_name

完成查看数据库

答案 7 :(得分:0)

类似于上面的Andrew E,但进行了一些更改,特别是在您未删除解决问题的迁移文件夹中的情况下

1-在完整的迁移文件夹中,只需检查000 * .py文件(从最高到初始)开始计数,直到找到定义模型的文件为止,例如0002_entry.py

2-python manage.py sqlmigrate应用名称0002> 0002_sql.txt以捕获SQL命令

3-编辑此文件以确保没有硬CR / LF,并且ALTER,CREATE INDEX命令每个都位于单独的一行上

4-登录到您的数据库(我有Postgres)并运行这些命令