django 如何知道已经运行了哪些迁移?

Posted

技术标签:

【中文标题】django 如何知道已经运行了哪些迁移?【英文标题】:How does django know which migrations have been run? 【发布时间】:2015-02-10 09:35:17 【问题描述】:

django 如何知道是否已经应用了迁移?它通常可以解决问题,但如果不正确,我不知道从哪里开始进行故障排除。

【问题讨论】:

【参考方案1】:

使用showmigrations 非常适合基本用例。希望您永远不必使用除此之外的任何东西。但是,如果您开始使用“替换”功能来压缩迁移,那么预期的行为可能会变得非常重要。

作为“Django 如何知道已运行哪些迁移?”问题的一部分答案,它们将应用迁移的记录存储在数据库中!

如果您想了解它们在数据库中存储的内容,请使用 Django shell 查看以下内容。

from django.db.migrations.recorder import MigrationRecorder
[(m.app, m.name) for m in MigrationRecorder.Migration.objects.all()]

对于简单的情况,这应该与showmigrations 显示的内容直接一一对应。但是,压缩了一些迁移(用其他迁移替换了一些迁移),您应该知道 Django 将存储在数据库中的迁移与存储在磁盘上的迁移进行比较,并且该过程变得非常重要。

因此,将这个答案细化为“Django 如何知道哪些迁移已运行?”命令showmigrations 显示了 Django 迁移解析算法的结果,该算法使用了多种信息源,其中一个包括一个表格,其中包含已应用的所有迁移的字面名称的名称。关于如何从一个到另一个...阅读源代码。

【讨论】:

【参考方案2】:

您可以简单地使用showmigrations 命令提供迁移列表

$ python manage.py showmigrations

是否应用每个迁移(由迁移名称旁边的 [X] 标记)。

~/workspace $ python manage.py showmigrations
admin
 [X] 0001_initial
 [X] 0002_logentry_remove_auto_add
auth
 [X] 0001_initial
 [X] 0002_alter_permission_name_max_length
 [X] 0003_alter_user_email_max_length
 [X] 0004_alter_user_username_opts
 [X] 0005_alter_user_last_login_null
 [X] 0006_require_contenttypes_0002
 [X] 0007_alter_validators_add_error_messages
contenttypes
 [X] 0001_initial
 [X] 0002_remove_content_type_name
sessions
 [X] 0001_initial

【讨论】:

Showmigrations 列出了 Django 知道的迁移以及它们是否已被应用。但是它通过查看 django_migrations 表来生成这个列表。每当您运行迁移或成功回滚迁移时,此表都会更新。【参考方案3】:

正如其他答案所述,django 有一个特殊的表 django_migrations 用于保存迁移历史记录。

如果您有兴趣深入挖掘,请参阅负责在数据库中记录迁移的MigrationRecorder class。另外,这是django_migrations 表的底层模型:

class Migration(models.Model):
    app = models.CharField(max_length=255)
    name = models.CharField(max_length=255)
    applied = models.DateTimeField(default=now)

    class Meta:
        apps = Apps()
        app_label = "migrations"
        db_table = "django_migrations"

    def __str__(self):
        return "Migration %s for %s" % (self.name, self.app)

【讨论】:

【参考方案4】:

如果是django1.7,它将历史存储到数据库,表django_migrations。 South 还将迁移存储在数据库中,您可以启用在 django admin 中显示迁移历史记录的功能。

【讨论】:

看起来 South 在表 south_migrationhistory 中存储了迁移历史,虽然我还没有找到官方文档来确认。 您知道如何启用该功能以在管理员中显示迁移吗?我在文档中找不到它,我自己也没有运气。 @skolsuper 也许有更好的解决方案,但您可以像这里github.com/django/django/blob/… 那样描述迁移模型,然后像通常的模型一样简单地将其包含给管理员【参考方案5】:

Django 将一条记录写入表 django_migrations,其中包含一些信息,例如迁移所属的应用程序、迁移的名称和应用日期。

【讨论】:

@alecxe 在我的迁移历史表中存在行applied timestamp @coldmind 我的错,这是正确的。 applied 不是布尔标志 - 它是 datetimefield。谢谢! 在我的情况下,django_migrations 表中已经有一个条目,其中一行列出了我的应用程序和迁移(在这种情况下为0001 initial)。然而,当我打电话给./manage.py migrate 时,django 仍然尝试应用相同的迁移。 ./manage.py migrate <app> --fake-initialdjango_migrations 中创建了另一行,具有相同的 appname 字段(当然,不同的 appliedid)。然后./manage.py migrate 最终报告没有要申请的迁移。这表明接受的答案是不完整的 - 为什么 django 会尝试应用已经列出的迁移?

以上是关于django 如何知道已经运行了哪些迁移?的主要内容,如果未能解决你的问题,请参考以下文章

不知道为啥 django South 试图运行反向迁移

在 Django 中,您可以在不总是生成迁移的情况下运行种子数据吗?

如何运行迁移并添加电话号码

django迁移地狱,丢了一张桌子。试图找回它

石墨烯代码在 Django 数据迁移之前运行

如何使用xampp mysql配置django?