gpt4 book ai didi

python - 在 Django 中使用多个数据库,只有一张表 "django_migrations"

转载 作者:行者123 更新时间:2023-12-04 02:25:40 28 4
gpt4 key购买 nike

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

需要在远程数据库上创建一个表,我创建了迁移,运行它和表 django_migrations被创建。我只想只有一张 table django_migrations , 在默认数据库中。
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

我收到以下警告:

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 的表格在 remote 中创建数据库,并在 django_migrationsremote数据库迁移被标记为已应用。

编辑:
如何强制 Django 只使用一张表 django_migrations ,但仍将迁移应用到不同的数据库?

如何在不同的数据库中应用迁移以便不引发警告?

最佳答案

由于对我的问题的评论,我做了一些研究并得出了以下发现。

使用多个数据库导致创建表 django_migrations当使用迁移时。没有选项可以仅在一张表中记录迁移 django_migrations ,作为来自 Kamil Niski 的评论解释。阅读文件 django/db/migrations/recorder.py 后就很清楚了.

我将举例说明一个项目 foo和一个应用程序 bar项目内部。应用程序 bar只有一种型号 Baz .

我们创建项目:

django-admin startproject foo

现在我们在主项目目录中有这些内容:
- foo
- manage.py

我习惯将项目目录内的所有应用程序分组:
mkdir foo/bar
python manage.py bar foo/bar

在文件中 foo/settings.py我们调整设置以使用两个不同的数据库,出于本示例的目的,我们使用 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 将使用默认数据库。
Operations to perform:  Apply all migrations: admin, auth, contenttypes, sessionsRunning 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 has applied all migrations to the default database:

1           contenttypes  0001_initial  2019-11-13 16:51:04.7673822           auth          0001_initial  2019-11-13 16:51:04.7922453           admin         0001_initial  2019-11-13 16:51:04.8274544           admin         0002_logentr  2019-11-13 16:51:04.8466275           admin         0003_logentr  2019-11-13 16:51:04.8644586           contenttypes  0002_remove_  2019-11-13 16:51:04.8922207           auth          0002_alter_p  2019-11-13 16:51:04.9064498           auth          0003_alter_u  2019-11-13 16:51:04.9239029           auth          0004_alter_u  2019-11-13 16:51:04.94170710          auth          0005_alter_u  2019-11-13 16:51:04.95837111          auth          0006_require  2019-11-13 16:51:04.96552712          auth          0007_alter_v  2019-11-13 16:51:04.98153213          auth          0008_alter_u  2019-11-13 16:51:05.00414914          auth          0009_alter_u  2019-11-13 16:51:05.01970515          auth          0010_alter_g  2019-11-13 16:51:05.03702316          auth          0011_update_  2019-11-13 16:51:05.05444917          sessions      0001_initial  2019-11-13 16:51:05.063868

Now we create the model 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 ) 并创建迁移:
python manage.py makemigrations bar

在我们运行迁移之前,我们创建 routers.pybar应用程序:
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

and register it in foo/settings.py:

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

现在最简单的方法是运行 bar 的迁移。进 remote数据库:
python manage.py migrate bar --database=remote
Operations to perform:  Apply all migrations: barRunning migrations:  Applying bar.0001_initial... OK

The migrations has been applied to the remote database:

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

When we run:

python manage.py runserver

将发出以下警告:

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.



不过,一切似乎都运行良好。但是,收到此警告并不令人满意。

正确的方法是按照此 answer 中的建议为每个数据库运行所有迁移。 .

它看起来像这样:
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 , sessions等将仅在 default 中创建数据库,如 routers.py 中所指定.表 django_migrationsremote数据库也会有这些迁移的记录。

这是一篇很长的文章,但我希望它能对此有所了解,在我看来,官方 documentation 中没有彻底解释的问题.

关于python - 在 Django 中使用多个数据库,只有一张表 "django_migrations",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58608319/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com