我在setting.py
文件中定义了两个数据库。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'monitoring',
'USER': 'root',
'PASSWORD': '',
'HOST': 'localhost',
'PORT': '',
},
'source' :{
'ENGINE': 'django.db.backends.mysql',
'NAME': 'source_db',
'USER': '*****',
'PASSWORD': '*****',
'HOST': '*****',
'PORT': '****',
}
}
我需要访问source_db中的一些表,除非我迁移数据库,否则django不允许这样做。因此,一旦我们运行命令python manage.py migrate --database=source
,Django就会在服务器db中创建一些表。由于我们不允许在服务器数据库中创建表,有没有办法阻止django这样做,还是以任何方式访问表而不迁移数据库?
这是我们不想创建的表列表。
+--------------------------------+
| Tables_in_source_db |
+--------------------------------+
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| dashboard_monitoring_features |
| dashboard_monitoring_modelinfo |
| dashboard_monitoring_product |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
+--------------------------------+
答案 0 :(得分:0)
如果您不想要特定的表格,请删除
'django.contrib.auth`,
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.admin',
和dashboard
app
INSTALLED_APPS
的
答案 1 :(得分:0)
如果要在default
数据库而不是source
数据库中迁移/创建表,则必须在运行迁移时定义应用程序和数据库。像:
python manage.py migrate dashboard --database=default
这将在dashboard
应用中运行迁移,并在default
数据库中创建表。
您要做的下一件事是将source
模型设置为non-managed。您可以通过在模型的元类中指定managed = False
来完成:
class YourModel(models.Model):
... your fields here ...
class Meta:
managed = False
如果为False,则不会创建或删除数据库表操作 为这个模型执行。如果模型代表一个,这很有用 现有表或由其他人创建的数据库视图 装置
答案 2 :(得分:0)
可能没有人知道问题作者试图做什么。因此,让我从上下文开始。
默认情况下,Django使用名为default
的数据库。假设我在CustomModel
中有一个CustomApp
,应该在名为source_db
的新数据库中为其创建表。
因此,我们有两个数据库:1)default
和2)source_db
。
我们希望仅在auth_group
中创建诸如django.contrib.auth
之类的应用所需的诸如default
之类的默认表。 source_db
应该只有CustomApp
中的表。我们该怎么做?
首先,请参阅Multiple Databases(官方文档)以了解路由基础。特别注意allow_migrate()
。让我坚持认为,了解此文档对于理解此解决方案的其余部分至为重要。
让我们开始吧:
在您的CustomModel
中,在元数据中设置managed = True
:
class CustomModel(models.Model):
# your fields here ...
class Meta:
managed = True
这指定Django应该照顾该模型的表创建和更改。
为CustomDBRouter
中的表编写CustomApp
。 (有关此问题,请参考Multiple Databases)。不要忘记定义allow_migrate()
。
def allow_migrate(self, db, app_label, model_name=None, **hints):
"""
Make sure the 'CustomApp' only appear in the 'source_db' database.
"""
if app_label == 'CustomApp':
# if app=CustomApp and db=source_db, migrate
return db == 'source_db'
return None # No suggestions, ask the next router in the list
转到您的settings.py
并按以下方式拆分列表INSTALLED_APPS
:
MY_APPS = [ # List of apps defined by you
'customApp'
]
INSTALLED_APPS = [ # Full list of apps
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles'
] + MY_APPS
现在将新路由器添加到project-app(默认应用)文件夹(您拥有settings.py
的文件夹)
该路由器应如下所示:
from project.settings import MY_APPS
class DefaultDBRouter(object):
def allow_migrate(self, db, app_label, model_name=None, **hints):
"""
If an app is not defined by me, migrate only if database is 'default'
"""
if app_label not in MY_APPS:
return db == 'default'
return False
现在将DefaultDBRouter
添加到DATABASE_ROUTERS
中的settings.py
时,请确保这是列表中的最后一个路由器。这是最重要的,因为路由器按照列出的顺序进行处理。
DATABASE_ROUTERS = ['customApp.dbRouter.CustomDBRouter', 'project.dbRouter.DefaultDBRouter']
最后,您可以使用以下命令进行迁移:
python manage.py makemigrations # Make migrations for all apps
python manage.py migrate # Do migrations to 'default'
python manage.py migrate --database=source_db # Do migrations to 'source'
现在,在进行迁移时,请遵循以下步骤:
python manage.py makemigrations # Make migrations for all apps
python manage.py migrate # Do migrations to `default`
python manage.py migrate customApp --database=source_db
# Do migrations to 'source_db' from `customApp` only
由于像auth_group
这样的表不属于customApp
的迁移,因此不会在最后一个命令中创建它们。您可以将这3个命令添加到Shell脚本中以简化工作。请注意,随着应用程序和数据库数量的增加,此方法看起来很脏。另一方面,Solution-1提供了一种干净的方法。
答案 3 :(得分:0)
正在寻找另一个问题,但偶然发现了这个问题。答案是使用数据库路由器。在项目的root_app
中创建一个文件(我叫我的model.py
)并添加以下设置:
from <app> import models as app_models
class DatabaseRouter(object):
def db_for_read(self, model, **hints):
""" Route for when Django is reading the model(s). """
if model in (
app_models.<name>,
):
return "project_db"
return "default"
def db_for_write(self, model, **hints):
""" Route for when Django is writing the model(s). """
if model in (
app_models.<name>
):
return "project_db"
return "default"
然后在您的settings.py
中,您应该具有:
DATABASES = {
"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:"},
"project_db": { ... },
}
以及以下行:
DATABASE_ROUTERS = ("root_app.models.DatabaseRouter",)
您应该可以根据自己的喜好概括以上内容。