检查待处理的Django迁移

Mos*_*lum 30 python django django-migrations

在Django中,是否有一种简单的方法可以检查是否已运行所有数据库迁移?我发现manage.py migrate --list,它给了我想要的信息,但格式不是机器可读的.

对于上下文:我有一个脚本,在迁移数据库之前不应该开始运行.由于各种原因,从正在运行迁移的进程发送信号会很棘手.所以我想让我的脚本定期检查数据库以查看是否所有迁移都已运行.

Ern*_*Ten 48

贝壳

到目前为止,我发现的唯一简单解决方案就是运行

./manage.py showmigrations | grep '\[ \]'
Run Code Online (Sandbox Code Playgroud)

如果已应用所有迁移,将输出空字符串.

但是,它与输出格式密切相关.

蟒蛇

我检查了源代码 migrate命令看起来这应该可以解决问题:

from django.db.migrations.executor import MigrationExecutor
from django.db import connections, DEFAULT_DB_ALIAS


def is_database_synchronized(database):
    connection = connections[database]
    connection.prepare_database()
    executor = MigrationExecutor(connection)
    targets = executor.loader.graph.leaf_nodes()
    return not executor.migration_plan(targets)

# Usage example.
if is_database_synchronized(DEFAULT_DB_ALIAS):
    # All migrations have been applied.
    pass
else:
    # Unapplied migrations found.
    pass
Run Code Online (Sandbox Code Playgroud)

  • 在Django 1.7或更高版本中,您可以使用:`./ admin showmigrations --list`或`./manage showmigrations --plan` (4认同)

min*_*usf 16

1.10发行说明:

makemigrations --check当检测到没有迁移的模型更改时,新选项使命令以非零状态退出.

  • 虽然我认为这是对更重要的问题“如何知道我是否需要进行迁移 [然后应用这些迁移]?”的答案。OP 很可能主要或次要地追求它,它很容易被解释为不是对实际提出的特定问题的完全答案。我会说所有其他答案都需要一半的过程,而您的答案则是另一半。我觉得从技术上讲,OP 只能想要一半,但实际上,对于像所提出的那样模糊的问题,两半都应该参与任何真正有用的答案。 (2认同)

Par*_*us- 15

尝试,

python manage.py migrate --list | grep "\[ \]\|^[a-z]" | grep "[ ]" -B 1
Run Code Online (Sandbox Code Playgroud)

回报,

<app_1>
 [ ] 0001_initial
 [ ] 0002_auto_01201244
 [ ] 0003_auto_12334333

<app_2>
 [ ] 0031_auto_12344544
 [ ] 0032_auto_45456767
 [ ] 0033_auto_23346566

<app_3>
 [ ] 0008_auto_3446677
Run Code Online (Sandbox Code Playgroud)


更新:

如果您已更新Django版本> = 1.11,请使用以下命令,

python manage.py showmigrations | grep '\[ \]\|^[a-z]' | grep '[  ]' -B 1
Run Code Online (Sandbox Code Playgroud)


Tom*_*cik 8

3.1 发行说明

当检测到未应用的迁移时,新的 migrate --check 选项使命令以非零状态退出。

https://docs.djangoproject.com/en/3.1/ref/django-admin/#cmdoption-migrate-check

所以最后我们可以

python manage.py migrate --check


Jan*_*lik 7

./manage.py showmigrations#检查是否应用了已经进行的迁移
(或:./manage.py showmigrations someApp#仅针对特定应用)

./manage.py makemigrations --dry-run#检查是否要进行迁移
(或:./manage.py makemigrations someApp --dry-run#仅针对特定应用进行迁移)

./manage.py makemigrations#进行迁移
(或:./manage.py makemigrations someApp#仅针对特定应用进行迁移)

./manage.py showmigrations#检查是否应用了已经进行的迁移
(或:./manage.py showmigrations someApp#仅针对特定应用)

./manage.py sqlmigrate someApp 0001 #查看特定应用和迁移的SQL更改

./manage.py migrate#apply迁移
(或:./manage.py migrate someApp#仅针对特定应用程序)

./manage.py showmigrations#检查是否应用了已经进行的迁移
(或:./manage.py showmigrations someApp#仅针对特定应用)

./manage.py makemigrations --dry-run#检查是否要进行迁移
(或:./manage.py makemigrations someApp --dry-run#仅针对特定应用进行迁移)

PS:
./manage.py migrate someApp zero#取消对特定应用程序的所有迁移

  • 对于那些可能尝试编辑此答案的人...此答案中的重复步骤并非偶然,如果您花时间理解问题或答案,您就会知道这一点。如果您不检查自己(正如本答案中的重复步骤所鼓励的那样),您将永远无法掌握这个过程,而且几乎肯定会破坏某些东西。如果这是一个不复杂、完全安全的过程,答案就不会那么长(即使没有重复)。如果没有重大的 Django 开发,我预计不会对此答案做出任何非常有用的更改。 (2认同)

chs*_*ann 6

这是我的 Python 解决方案,用于获取有关迁移状态的一些信息:

from io import StringIO  # for Python 2 use from StringIO import StringIO  
from django.core.management import call_command 

def get_migration_state():
    result = []
    out = StringIO()
    call_command('showmigrations', format="plan", stdout=out)
    out.seek(0)
    for line in out.readlines():
        status, name = line.rsplit(' ', 1)
        result.append((status.strip() == '[X]', name.strip()))
    return result
Run Code Online (Sandbox Code Playgroud)

该函数的结果如下所示:

[(True, 'contenttypes.0001_initial'),
 (True, 'auth.0001_initial'),
 (False, 'admin.0001_initial'),
 (False, 'admin.0002_logentry_remove_auto_add')]
Run Code Online (Sandbox Code Playgroud)

也许它对你们中的一些人有帮助..