【问题标题】:django single app multiple dbs: same tables get created in all dbsdjango 单个应用程序多个数据库:在所有数据库中创建相同的表
【发布时间】:2020-12-29 16:10:06
【问题描述】:

我正在测试开发一个带有单个应用程序(app_name)的 django 项目,我希望有 2 个模型(例如:model_Amodel_B),它们的实例存储在单独的数据库中(例如:DB_A.sqlite3DB_B.sqlite3)。我还有第三个数据库 (DB_users.sqlite3) 用于存储与身份验证、会话等相关的任何内容。

我正在尝试根据 django 文档实现多个数据库,使用数据库路由等,但我注意到在迁移时,在这 3 个数据库中的每一个中,都会为这两个模型创建不相关的表。例如,DB_A 将创建 my_app_model_Amy_app_model_B 表。但问题是my_app_model_B 只能存储在DB_B 中。

这可能是什么原因/如何确保仅在正确的数据库中创建相关表?

=== 编辑===

让我确实添加代码,因为这样更容易查看。为简单起见,我将缩小到docs sqlite DB 中的单个 Document 模型,以及用于用户信息、会话等的单独 auth sqlite DB。Django 项目名称为 docs_rev,django 应用程序名称为 @987654337 @。当我创建文档或用户时,实例位于正确数据库中的正确表中,但是我看到的问题是两个数据库具有相同的表集,恕我直言,这很奇怪。例如。 docs db 也有所有的 auth* 表(虽然是空的),auth db 有 reviewer_document 表(虽然是空的)。

我的代码: docs_rev\docs_rev\settings.py

...

DATABASES = {
    
    'default':{},

    'auth': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'auth.sqlite3'),
    },

    'docs' : {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'docs.sqlite3'),
    },
}

DATABASE_ROUTERS = [
    'reviewer.router.authRouter',
    'reviewer.router.docsRouter', 
]

...

docs_rev\docs_rev\urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('reviewer/', include ('reviewer.urls')),
    path('', RedirectView.as_view(url='reviewer/', permanent=True)),
    path('accounts/', include('django.contrib.auth.urls')),
]

docs_rev\reviewer\urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('docs/', views.DocsListView.as_view(), name='docs'),
    path('doc/<uuid:pk>', views.DocDetailView.as_view(), name='document-detail'),
]

docs_rev\reviewer\models.py

...
class Document(models.Model):

...
    class Meta:
        app_label = 'reviewer'

    def __str__(self):
        return str(self.id)
    
    def get_absolute_url(self):
        return reverse('document-detail', args=[str(self.id)])

docs_rev\reviewer\router.py

class authRouter:
    route_app_labels = {'admin', 'auth', 'contenttypes', 'flatpages', 'redirects', 'sessions', 'sites'}

    def db_for_read(self, model, **hints):
        if model._meta.app_label in self.route_app_labels:
            return 'auth'
        return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label in self.route_app_labels:
            return 'auth'
        return None

    def allow_relation(self, obj1, obj2, **hints):
        if (
            obj1._meta.app_label in self.route_app_labels or
            obj2._meta.app_label in self.route_app_labels
        ):
           return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if app_label in self.route_app_labels:
            return True
        return None

class docsRouter(object): 

    route_app_labels = {'reviewer'}

    def db_for_read(self, model, **hints):
        if model._meta.app_label in self.route_app_labels:
            return 'docs'
        return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label in self.route_app_labels:
            return 'docs'
        return None
    
    def allow_relation(self, obj1, obj2, **hints):
        if obj1._meta.app_label in self.route_app_labels or \
           obj2._meta.app_label in self.route_app_labels:       
            return True
        return None
    
    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if app_label in self.route_app_labels:
            return True
        return None

【问题讨论】:

标签: python django django-models


【解决方案1】:

数据库路由器的重要部分是route_app_labels 这可确保这些应用始终使用指定的数据库。

https://docs.djangoproject.com/en/3.1/topics/db/multi-db/

class AuthRouter:
    route_app_labels = {'auth', 'contenttypes'}
    ...rest of router code...

另外,请仔细检查 settings.py 中的 DATABASE_ROUTERS 是否正确。

DATABASE_ROUTERS = ['path.to.AuthRouter', 'path.to.PrimaryReplicaRouter']

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-16
    • 1970-01-01
    • 2017-12-11
    • 2019-12-02
    • 2018-12-19
    • 1970-01-01
    • 2017-03-04
    相关资源
    最近更新 更多