在Django中仅使用一个表“ django_migrations”使用多个数据库 [英] Use multiple databases in Django with only one table "django_migrations"

查看:429
本文介绍了在Django中仅使用一个表“ django_migrations”使用多个数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于Django中的项目,我必须使用两个数据库:默认远程。我创建了 routers.py ,并且一切正常。

For a project in Django I have to use two databases: default and remote. I have created routers.py and everything works fine.

需要在远程计算机上创建表数据库,我创建了迁移,然后运行它并创建了 django_migrations 表。我只想在默认数据库中只有一个表 django_migrations

There was a requirement to create a table on the remote database and I created migration, run it and the table django_migrations was created. I want to have only one table django_migrations, in the default database.

<$ c $的相关部分c> routers.py 在这里:

class MyRouter(object):
     # ...
     def allow_migrate(self, db, app_label, model_name=None, **hints):
         if app_label == 'my_app':
             return db == 'remote'
         return None

我像这样运行迁移:

python manage.py migrate my_app --database=remote

现在,当我这样做时:

python manage.py runserver

我收到以下警告:


您有1个未应用的迁移(s)。在为应用程序应用迁移之前,您的项目可能无法正常工作:my_app。

运行'python manage.py migration'来应用它们。

You have 1 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): my_app.
Run 'python manage.py migrate' to apply them.

my_app 的表在远程数据库中以及在在远程数据库内的 django_migrations 中,迁移被标记为已应用。

The tables for my_app are created in the remote database, and in django_migrations inside the remote database the migrations are marked as applied.

编辑:

如何强制Django仅使用一个表 django_migrations ,但仍将迁移应用到其他数据库中?


How to force Django to use only one table django_migrations, but still apply the migrations into different databases?

如何在不同的数据库中应用迁移,从而不发出警告?

How to apply the migrations in different databases so that no warnings are raised?

推荐答案

感谢对我的问题的评论,我进行了一些研究并得出以下发现。

Thanks to the comments on my question I did some research and came up with the following findings.

使用多个数据库可以创建表 django_migrations (使用迁移时)。没有选择将迁移记录在一个表 django_migrations 中,如 Kamil Niski 解释。读取文件 django / db / migrations / recorder.py

Using multiple databases results in creating a table django_migrationswhen migrations are used. There is no option to record the migrations in only one table django_migrations, as the comment from Kamil Niski explains. This is clear after reading the file django/db/migrations/recorder.py.

我将举例说明项目 foo 和项目内的应用程序 bar 。应用程序 bar 只有一个模型 Baz

I will illustrate an example with a project foo and an app bar inside the project. The app bar has only one model Baz.

我们创建项目:

django-admin startproject foo

现在我们在主项目目录中包含以下内容:

Now we have these contents inside the main project directory:

- foo
- manage.py

我习惯将所有应用分组到项目目录中:

I have a habit to group all apps inside the project directory:

mkdir foo/bar
python manage.py bar foo/bar

在文件 foo / settings.py 中,我们调整设置以使用两个不同的数据库,就本例而言,我们使用 sqlite3

In the file foo/settings.py we adjust the settings to use two different databases, for the purposes of this example we use sqlite3:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db1.sqlite3'),
    },
    'remote': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db2.sqlite3'),
    }
}

现在我们运行迁移:

python manage.py migrate --database=default

这将运行所有迁移,-database = default 部分是可选的,因为如果未指定,则Django使用默认数据库。

This runs all migrations, the part --database=default is optional, because if not specified Django uses the default database.


Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying sessions.0001_initial... OK

Django已将所有迁移应用到默认数据库:

Django has applied all migrations to the default database:


1           contenttypes  0001_initial  2019-11-13 16:51:04.767382
2           auth          0001_initial  2019-11-13 16:51:04.792245
3           admin         0001_initial  2019-11-13 16:51:04.827454
4           admin         0002_logentr  2019-11-13 16:51:04.846627
5           admin         0003_logentr  2019-11-13 16:51:04.864458
6           contenttypes  0002_remove_  2019-11-13 16:51:04.892220
7           auth          0002_alter_p  2019-11-13 16:51:04.906449
8           auth          0003_alter_u  2019-11-13 16:51:04.923902
9           auth          0004_alter_u  2019-11-13 16:51:04.941707
10          auth          0005_alter_u  2019-11-13 16:51:04.958371
11          auth          0006_require  2019-11-13 16:51:04.965527
12          auth          0007_alter_v  2019-11-13 16:51:04.981532
13          auth          0008_alter_u  2019-11-13 16:51:05.004149
14          auth          0009_alter_u  2019-11-13 16:51:05.019705
15          auth          0010_alter_g  2019-11-13 16:51:05.037023
16          auth          0011_update_  2019-11-13 16:51:05.054449
17          sessions      0001_initial  2019-11-13 16:51:05.063868

现在我们创建模型 Baz

models.py

from django.db import models

class Baz(models.Model):
    name = models.CharField(max_length=255, unique=True)

将应用程序 bar 注册到 INSTALLED_APPS foo / settings.py )并创建迁移:

register the app bar into INSTALLED_APPS (foo/settings.py) and create the migrations:

python manage.py makemigrations bar

在运行迁移之前,我们在<$ c $中创建 routers.py c> bar app:

Before we run the migrations we create routers.py inside the bar app:

class BarRouter(object):
    def db_for_read(self, model, **hints):
        if model._meta.app_label == 'bar':
            return 'remote'
        return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label == 'bar':
            return 'remote'
        return None

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

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if app_label == 'bar':
            return db == 'remote'
        if db == 'remote':
            return False
        return None

并将其注册到 foo / settings.py

DATABASE_ROUTERS = ['foo.bar.routers.BarRouter']

天真方法是将 bar 的迁移运行到远程数据库中:

Now the naive approach would be to run the migrations for bar into the remote database:

python manage.py migrate bar --database=remote



Operations to perform:
  Apply all migrations: bar
Running migrations:
  Applying bar.0001_initial... OK

迁移已应用于远程数据库:

1           bar         0001_initial  2019-11-13 17:32:39.701784

运行时:

python manage.py runserver

将发出以下警告:


您有1个未应用的迁移。您的项目可能无法正常运行
,直到您为应用应用迁移:bar。

运行'python manage.py migration'来应用它们。

You have 1 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): bar.
Run 'python manage.py migrate' to apply them.

一切似乎都很好。

正确的方法是按照此答案

它看起来像这样:

python manage.py migrate --database=default
python manage.py migrate --database=remote

,并为 bar 创建迁移后:

python manage.py migrate bar --database=default
python manage.py migrate bar --database=remote

路由器将注意表 bar_baz 仅在 remote 数据库,但Django会将这两个数据库中的迁移标记为已应用。还有用于 auth admin 会话等的表。将仅在 default 数据库中创建,如 routers.py 中所指定。 remote 数据库中的表 django_migrations 也将包含这些迁移的记录。

The router will take care that the table bar_baz is created only in the remote database, but Django will mark the migrations as applied in both databases. Also the tables for auth, admin, sessions, etc. will be created only in the default database, as specified in routers.py. The table django_migrations in the remote database will have records for these migrations too.

这是一个长期的阅读,但我希望对此有所了解,在官方文档

It is a long reading, but I hope it sheds some light on this, in my opinion, not thoroughly explained issue in the official documentation.

这篇关于在Django中仅使用一个表“ django_migrations”使用多个数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆