Django迁移未应用迁移更改

Django迁移未应用迁移更改,django,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 perfo

使用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迁移的新技术,而不是旧的南方方法。

删除迁移目录从来都不是一个好主意,因为django然后会忘记应用了哪些迁移,哪些没有(并且一旦应用程序部署到某个地方,就很难恢复同步)

免责声明:每当发生类似情况时,如果数据库包含任何有价值的内容,最好对其进行备份。如果在早期开发中没有必要这样做,但是一旦后端上的事情不同步,事情就有可能变得更糟。:-)


要恢复,您可以尝试重置模型,使其与添加/删除字段之前的模型完全匹配。然后你就可以跑了

$ python manage.py makemigrations myproj
这将导致初始迁移(
0001\u initial…
)。然后,您可以告诉Django伪造该迁移,这意味着告诉它将其内部计数器设置为此
0001_initial

对于Django 1.7:

$ python manage.py migrate myproj
Django>=1.8时:

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

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

确保
migrations/
文件夹中包含一个
\u init\uuuuuuuuuuuuuuuuuuupy
文件


在我的例子中,迁移没有反映在mysql数据库中。我手动从mysql数据库中的“django_migrations”表中删除了“myapp”(在您的例子中是“myproj”)行,并再次运行相同的迁移命令

我觉得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

或者复制并粘贴它,等等。

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

以上大多数解决方案都有助于解决这个问题,但是,我想指出另一种可能(尽管很少)数据库路由器的
allow\u migrate
方法可能返回
False
,而它本应返回
None

Django有一个设置,用于确定在执行数据库查询时使用哪个数据库

从文档中:

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

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

  • db_用于_读取(型号,**提示)
  • db_用于_写入(型号,**提示)
  • 允许_关系(obj1、obj2、**提示)
  • 允许迁移(数据库、应用程序标签、型号名称=无、**提示)
从:

允许迁移(数据库、应用程序标签、型号名称=无、**提示)

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

对于您尝试运行的迁移,可能有一个数据库路由器按顺序返回False,在这种情况下,特定操作将不会运行

pip install django-extensions
并将其添加到
settings.py的安装应用程序中

INSTALLED_APPS = [
    'django_extensions'
]
然后跑

python ./manage.py reset_db
然后再次运行迁移

python manage.py makemigrations
python manage.py migrate

现在,为已安装的应用程序运行迁移

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


完成了!查看您的数据库…

与上面的Andrew E类似,但有一些更改,特别是在您寻求解决问题时没有删除迁移文件夹的情况下

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

2-python manage.py sqlmigrate app name 0002>0002_sql.txt以捕获sql命令

3-编辑此文件以确保没有硬CR/LFs,并且ALTER、CREATE INDEX命令都位于各自的单行上


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

myproj是否已添加到已安装的应用程序中?对于以前创建的模型,它会为您提供
0001\u首字母
,这似乎很奇怪。您是否从较旧的Django版本进行了更新?没有。Django 1.7.7只是一个干净的开始。转到您的迁移文件夹,删除
0001_initial.py
文件,然后运行
python manage.py makemigrations myproj
然后运行
python manage.py migrate
。这是您对应用程序
myproj
的首次迁移。试试这个,让我们知道结果。谢谢。不要删除文件夹,这一点很重要。我让它工作了,但是——伪初始选项不被识别。知道为什么吗?是的,我的错<代码>--Django 1.8中添加了伪首字母
。在文档中:“在迁移中添加了--false initial标志;以前,如果检测到现有表,则始终会自动假应用初始迁移。”更新了答案以更精确地说明这一点。希望向上投票并让人们知道这解决了我的问题!如果没有别的事,请记住这一点。这为我节省了半个小时的时间
python manage.py makemigrations your_app_name
python manage.py migrtate your_app_name