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-initial
在 django_migrations
中创建了另一行,具有相同的 app
和 name
字段(当然,不同的 applied
和 id
)。然后./manage.py migrate
最终报告没有要申请的迁移。这表明接受的答案是不完整的 - 为什么 django 会尝试应用已经列出的迁移?以上是关于django 如何知道已经运行了哪些迁移?的主要内容,如果未能解决你的问题,请参考以下文章