django 是如何知道是否已经应用了迁移?它通常是正确的,但是当它不正确时,我不知道从哪里开始进行故障排除。
5 回答
Django 将一条记录写入表中django_migrations
,其中包含一些信息,例如迁移所属的应用程序、迁移的名称以及应用的日期。
您可以简单地使用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
正如其他答案所述,django 有一个特殊的表django_migrations
,用于保存迁移历史记录。
如果您有兴趣深入挖掘,请参阅负责在数据库中记录迁移的MigrationRecorder
类。此外,这是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)
Using showmigrations
is great for the basic use case. Hopefully you never have to use anything beyond that. However, if you start using the "replaces" functionality to squash migrations, the expected behavior can become extremely non-trivial.
As a part of the answer to the question "how does Django know what migrations have been run?", they store records of applied migrations in the database!
If you want to have a peek at what they store in the database, take a gander at the following using the Django shell.
from django.db.migrations.recorder import MigrationRecorder
[(m.app, m.name) for m in MigrationRecorder.Migration.objects.all()]
For simple cases, this should directly correspond 1-to-1 with what you are showed with showmigrations
. However, squashed some migrations (replaced some migrations with others), you should know that Django compares the migrations stored in the database to the migrations stored on disk, and the process becomes quite non-trivial.
So to refine this answer to "how does Django know which migrations have been run?" The command showmigrations
shows the result of Django's migration resolution algorithm, which uses several sources of information, one of which includes a table with the names of all the literal names of the migrations that have been applied. For how you go from one to the other... read the source code.
如果是 django1.7,它将历史存储到数据库 table django_migrations
。South 还将迁移存储在数据库中,您可以启用功能以在 django admin 中显示迁移历史记录。