【问题标题】:Django Migration is not applying the migration changesDjango Migration 未应用迁移更改
【发布时间】:2015-04-27 17:33:28
【问题描述】:

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

【问题讨论】:

  • myproj 是否添加到 INSTALLED_APPS 中?
  • 对于以前创建的模型,它会给你一个0001_initial 似乎很奇怪。你是从旧的 Django 版本更新的吗?
  • 没有。从 django 1.7.7 开始。
  • 转到您的迁移文件夹,删除0001_initial.py 文件然后运行python manage.py makemigrations myproj 然后运行python manage.py migrate。这是您对应用程序 myproj 的初始迁移。所以试试这个,让我们知道结果。

标签: django


【解决方案1】:

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

为此浪费了半个小时。

【讨论】:

  • 这确实为我节省了半个小时
  • 哇。为什么是姜戈。为什么世界:(
【解决方案2】:

删除迁移目录绝不是一个好主意,因为 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 迁移,您可以按预期运行。

【讨论】:

  • 谢谢。不删除文件夹很重要。我让它工作了,但 --fake-initial 选项无法识别。知道为什么吗?
  • 是的,我的错。 --fake-initial 在 Django 1.8 中添加。来自文档:“添加了 --fake-initial 标志以进行迁移;以前,如果检测到现有表,初始迁移总是会自动伪造应用。”
  • 更新了答案,使其更准确。
【解决方案3】:

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

【讨论】:

  • 想要投票并让人们知道这解决了我的问题!如果没有其他问题,请记住这一点。
【解决方案4】:

上述大多数解决方案都有助于解决这个问题,但是,我想指出另一种可能(尽管很少见)的可能性,即数据库路由器的 allow_migrate 方法可能会返回 False,而它本应返回 @987654325 @。

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

来自文档:

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

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

  • db_for_read(model, **hints)
  • db_for_write(model, **hints)
  • allow_relation(obj1, obj2, **hints)
  • allow_migrate(db, app_label, model_name=None, **hints)

来自documentation

allow_migrate(db, app_label, model_name=None, **hints)

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

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

【讨论】:

  • 我必须翻阅十个溢出答案才能找到这个。我重命名了我的应用程序并一次性完成了它,这让我有点吃惊。
【解决方案5】:

我发现 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

或者复制粘贴等

【讨论】:

  • 我花了两天时间寻找这个解决方案。我希望我能多次投票,非常感谢!
【解决方案6】:
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

完成!查看您的数据库...

【讨论】:

    【解决方案7】:

    你可以删除你的数据库

    • python manage.py makemigrations
    • python manage.py 迁移
    • python manage.py migrate --run-syncdb

    并查看您的数据库是否正常工作 :)

    【讨论】:

      【解决方案8】:

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

      【讨论】:

        【解决方案9】:

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

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

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

        3 - 编辑此文件以确保没有硬 CR/LF,并且 ALTER、CREATE INDEX 命令各占一行

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-07-06
          • 2018-03-07
          • 1970-01-01
          • 2020-10-08
          • 1970-01-01
          • 1970-01-01
          • 2017-08-22
          • 2021-09-19
          相关资源
          最近更新 更多