【问题标题】:Why is django_migrations table in all databases为什么所有数据库中都有 django_migrations 表
【发布时间】:2016-08-22 01:27:09
【问题描述】:

我正在 Django 框架下建立一个网站,这个网站需要有不同的 SQL 方案,现在我成功创建了所有方案和所有东西,但是我不明白为什么表 django_migrations 在迁移后在每个模式中数据库。

  • 预期的数据库内容:

    AppDB 表是本应用定义的所有模型

    默认数据库表都是 Django 表(admin、contenttypes、auth、sessions)

  • 数据库内容:

    AppDB表就是这个app+django_migrations定义的所有模型

    DEFAULT 表都是 Django 表(admin、contenttypes、auth、sessions)+ django_migrations

这些是 2 个 dbs 的路由器:

class DefaultRouter(object):
    APPS = ['auth', 'sessions', 'admin', 'contenttypes']
    DB = 'default'

    def db_for_read(self, model, **hints):
        if model._meta.app_label in self.APPS:
            return self.DB
        return None

    def db_for_write(self, model, **hints):

        if model._meta.app_label in self.APPS:
            return self.DB

        return None

    def allow_relation(self, obj1, obj2, **hints):

        if obj1._meta.app_label in self.APPS or obj2._meta.app_label in self.APPS:
            return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):

        if app_label in self.APPS:
            return db == self.DB
        return None


class MyAppDBRouter(object):
    def db_for_read(self, model, **hints):
        return self.check_app_label(model)

    def db_for_write(self, model, **hints):
        return self.check_app_label(model)

    def allow_relation(self, obj1, obj2, **hints):
        if obj1._meta.app_label == 'myapp' or obj2._meta.app_label == 'myapp':
            return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if app_label == 'myapp':
            return db == 'appdb'
        return None

    @staticmethod
    def check_app_label(model):
        if model._meta.app_label == 'myapp':
            return 'appdb'
        return None

谢谢。

【问题讨论】:

  • 您已经写了一些 cmets 来回复答案,并且当前措辞的问题似乎无法解释您要问的是什么。您能否编辑说明以更好地解释您提出的问题?

标签: python django configuration database-migration multiple-databases


【解决方案1】:

django_migrations 表记录了哪些迁移已应用于该数据库。这是 Django 迁移系统了解数据库当前状态以及需要运行哪些迁移的机制。所以所有数据库都需要它。

现在,如果您有一个实际上不需要迁移的表(例如只读数据库),那么这可能会导致问题。这是this ticket的主题。

【讨论】:

  • 我认为你不明白我的要求,我的问题是,我有 2 个 db,一个应该包含 django 信息,另一个应该只包含我的应用程序的数据.当我迁移项目时,它会在两个数据库中使用相同的数据创建 django_migrations 表,我尝试了几乎所有方法来避免这种情况,但没有任何帮助
  • @NadirAlbajari:这是不可能的。您提到的其他表格只是可选应用程序,可以放在任何地方。迁移表不是可选的,它必须存在于每个数据库中,以便跟踪已在该数据库上应用了哪些迁移。
  • 感谢@Kevin,我明白这一点,但假设我有 2 个应用程序(app1、app2)和 2 个数据库(db1、db2),我希望在 db1 和db2 中的 app2 也是如此。但是 db1 中的迁移表包含 2 个应用程序的迁移,对于 db2 也是如此。发生这种情况有充分的理由吗?有没有办法将 2 个应用程序的迁移分开?再次感谢!!
  • @NadirAlbajari:Django 将这些迁移标记为已应用,但当allow_migrate() 返回False 时,它实际上并没有做任何事情。这就是documentation 中这句话中“静默”的意思:“请注意,迁移不会在返回False 的模型上静默地执行任何操作。”我的观点是这是一个糟糕的设计,你可以在我链接的票中看到对此的讨论。但这给您带来的实际问题是什么?
  • @KevinChristopherHenry 我知道这是旧的,但 5 年后我偶然发现了同样的问题,即为什么 django_migrations 表包含所有 dbs 的所有迁移,无论路由器设置如何阻止实际表获取迁移到不需要的数据库。我设法通过使用例如manage.py migrate polls --database=tutorial_db 来防止这种情况发生,其中polls 选项仅尝试在投票应用程序上运行迁移,因此django 的默认应用程序迁移不会出现在tutorial_dbdjango_migrations 表中。我想知道这是否是一个很好的解决方案。有什么想法吗?
【解决方案2】:

在 Django 1.7 版之前,没有 django_migrations 表。此后,Django 正确地包含了用于处理与数据库模式相关的更改的迁移,即字段定义的更改、db.models 中字段的添加或删除。

在早期版本中,开发人员使用 django_south_migration 应用程序来执行此操作,但由于几乎每个人都在使用它,因此 Django 包含在 1.7 版本以后。

现在来回答您的问题,django_migrations 表记录了应用于数据库的数据库模式的更改。该表有助于 django 应用之后创建的新迁移 python manage.py makemigrations

此表的 app 列记录了应用此迁移的应用的名称。如果您将转到任何 django 应用程序的迁移目录,您将看到格式为 0001_auto.py 等的迁移文件。
例如,如果此迁移已应用于数据库,您将找到一个条目在 django_migrations 表中具有 name=0001_auto 和 app=。

【讨论】:

  • 我认为你不明白我的要求,我的问题是,我有 2 个 db,一个应该包含 django 信息,另一个应该只包含我的应用程序的数据.当我迁移项目时,它会在两个数据库中使用相同的数据创建 django_migrations 表,我尝试了几乎所有方法来避免这种情况,但没有任何帮助
【解决方案3】:

我遇到了和你一样的问题,当我运行 python 'manage.py migrate --database=whatever' 时,当我检查 dbshel​​l 时,我只能看到一个名为 django_migrations 的表...... 做了一些调整让我无处可去,然后我将数据库的名称更改为路由器文件,它工作了!

例如,如果您将数据库命名为 primary_db ...您应该在路由器中使用您在设置文件中注册的名称。请参阅下面的示例...

DATABASES = {
    'default': {},
    'primary': {
        'NAME': 'primary_db.sqlite3',
        'ENGINE': 'django.db.backends.sqlite3',        
    },
    'secondary': {
        'NAME': 'secondary_db.sqlite3',
        'ENGINE': 'django.db.backends.sqlite3',
    }
}

在您的路由器文件中使用 primary 作为名称而不是 primary_db ...这是我犯的错误...希望这会有所帮助

【讨论】:

    猜你喜欢
    • 2011-07-18
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    • 2021-10-25
    • 2016-10-06
    • 2020-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多