python - django 单个应用程序多个数据库:在所有数据库中创建相同的表
问题描述
我正在使用单个应用程序(app_name)测试开发一个 django 项目,我想在其中拥有 2 个模型(例如:model_A
和model_B
),它们的实例存储在单独的数据库中(例如:DB_A.sqlite3
、DB_B.sqlite3
)。我还有第三个 DB ( DB_users.sqlite3
) 用于存储与身份验证、会话等相关的任何内容。
我正在尝试根据 django 文档实现多个数据库,使用数据库路由等,但我注意到在迁移时,在这 3 个数据库中的每一个中,都为这两个模型创建了不相关的表。例如,DB_A
将创建my_app_model_A
以及my_app_model_B
创建表。但事情my_app_model_B
应该只存储在DB_B
.
这可能是什么原因/如何确保仅在正确的数据库中创建相关表?
=== 编辑===
让我确实添加代码,因为这将更容易审查。为简单起见,我将缩小到sqlite DB中的单个Document
模型,以及用于用户信息、会话等的单独 sqlite DB。Django 项目名称为,django 应用程序名称为。当我创建文档或用户时,实例位于正确数据库中的正确表中,但是我看到的问题是两个数据库具有相同的表集,恕我直言,这很奇怪。例如db 也有所有的表(虽然是空的),而 db 有表(虽然是空的)。docs
auth
docs_rev
reviewer
docs
auth*
auth
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
解决方案
数据库路由器的重要部分是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...
此外,请仔细检查DATABASE_ROUTERS
settings.py 中的内容是否正确。
DATABASE_ROUTERS = ['path.to.AuthRouter', 'path.to.PrimaryReplicaRouter']
推荐阅读
- python - 有没有办法遍历 Gensim 的 Word2Vec 的向量?
- swift - 如何在 SwiftUI 中检测空内容作为输入内容?
- python-3.x - PyTelegramBotAPI 将最后一个帖子从频道转发到 user_id
- c - 除了无符号整数之外检查溢出的函数
- oracle - 在包内多次运行收集表统计信息会导致性能问题
- go - 在 go 中初始化结构时如何处理空值?
- typescript - 如何配置 Jest 以转换包含无效语法的模块?
- javascript - 点击更改背景颜色
- python - 余额错误:无法使用传递的 AccountID 和 PassPhrase 登录,或者在 PerfectMoney API 集成 python 中在此帐户/IP 上禁用 API
- elasticsearch - Elastic 中的搜索速度不依赖于分析器的使用