使用Django 1.11,我试图创建一个自定义路由器来根据使用的URL选择数据库。
例如,如果URL是customer1.example.com,我想选择数据库' customer1',同样如果是customer2.example.com,我希望它选择数据库& #39;的customer2'
我目前的设置效果很好!一个问题 - 当我尝试运行迁移(或其他依赖于数据库的命令)时,它会失败 - 即使我使用--database选项指定数据库,例如python manage.py migrate --database customer1
我不知道该怎么做,因为没有请求 - 我想实际返回命令行中指定的确切名称(例如customer1)。但它不是提示或任何其他选项。如何访问用于运行命令的命令行选项?否则我没有任何回报!
这是我的设置:
settings.py:
# Database to connect to
DATABASES = {
'default': {},
'customer1': {
'ENGINE': 'django.db.backends.oracle',
'NAME': 'xxxx',
'USER': 'yyyy',
'PASSWORD': 'zzzz',
'HOST': '192.168.168.176',
'PORT': '1521',
},
'customer2': {
'ENGINE': 'django.db.backends.oracle',
'NAME': 'xxxx',
'USER': 'yyyy',
'PASSWORD': 'zzzz',
'HOST': '192.168.168.179',
'PORT': '1521',
}
}
# Specify custom router
DATABASE_ROUTERS = ['workflow.router.RequestDatabaseRouter']
router.py(自定义路由器,使用线程获取当前请求对象)
from mainapp.threads import get_current_request
class RequestDatabaseRouter(object):
def db_for_read(self, model, **hints):
try:
request = get_current_request()
return request.META['HTTP_HOST'].split(':', 1)[0].split('.',1)[0]
except:
# ??????
def db_for_write(self, model, **hints):
try:
request = get_current_request()
return request.META['HTTP_HOST'].split(':', 1)[0].split('.',1)[0]
except:
# ??????
def allow_relation(self, obj1, obj2, **hints):
return True
def allow_migrate(self, db, app_label, model_name=None, **hints):
return True
我觉得应该在except块中的某些内容只返回"无论命令中的--database选项是什么" - 但我找不到一种方法来访问它。有什么建议吗?
以下是我尝试运行命令时的输出:python manage.py migrate --database=customer1
Operations to perform:
Apply all migrations: MOC, admin, auth, contenttypes, frontend, sessions, sites, viewflow
Running migrations:
No migrations to apply.
Traceback (most recent call last):
File "manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
utility.execute()
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/core/management/__init__.py", line 356, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/core/management/base.py", line 283, in run_from_argv
self.execute(*args, **cmd_options)
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/core/management/base.py", line 330, in execute
output = self.handle(*args, **options)
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/core/management/commands/migrate.py", line 227, in handle
self.verbosity, self.interactive, connection.alias, apps=post_migrate_apps, plan=plan,
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/core/management/sql.py", line 53, in emit_post_migrate_signal
**kwargs
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/dispatch/dispatcher.py", line 193, in send
for receiver in self._live_receivers(sender)
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/dispatch/dispatcher.py", line 193, in <listcomp>
for receiver in self._live_receivers(sender)
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/MOC/material/frontend/apps.py", line 158, in update_modules
_, created = DbModule.objects.get_or_create(label=module.label)
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/db/models/query.py", line 464, in get_or_create
return self.get(**lookup), False
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/db/models/query.py", line 374, in get
num = len(clone)
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/db/models/query.py", line 232, in __len__
self._fetch_all()
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/db/models/query.py", line 1118, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/db/models/query.py", line 53, in __iter__
results = compiler.execute_sql(chunked_fetch=self.chunked_fetch)
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 876, in execute_sql
sql, params = self.as_sql()
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 428, in as_sql
extra_select, order_by, group_by = self.pre_sql_setup()
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 46, in pre_sql_setup
self.setup_query()
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 37, in setup_query
self.select, self.klass_info, self.annotation_col_map = self.get_select()
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 227, in get_select
sql, params = self.compile(col, select_format=True)
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 373, in compile
sql, params = node.as_sql(self, self.connection)
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/db/models/expressions.py", line 695, in as_sql
return "%s.%s" % (qn(self.alias), qn(self.target.column)), []
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 364, in quote_name_unless_alias
r = self.connection.ops.quote_name(name)
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/db/backends/dummy/base.py", line 20, in complain
raise ImproperlyConfigured("settings.DATABASES is improperly configured. "
django.core.exceptions.ImproperlyConfigured: settings.DATABASES is improperly configured. Please supply the ENGINE value. Check settings documentation for more details.
`manage.py migrate --database customer1:
的结果{'customer1': {'PASSWORD': 'xxx', 'HOST': '192.168.168.176', 'NAME': 'mclaren', 'ENGINE': 'django.db.backends.oracle', 'PORT': '1521', 'USER': 'xxx'}, 'customer2': {'PASSWORD': 'xxx', 'HOST': '192.168.168.179', 'NAME': 'mclaren', 'ENGINE': 'django.db.backends.oracle', 'PORT': '1521', 'USER': 'xxx'}, 'default': {'PASSWORD': '', 'HOST': '', 'NAME': '', 'TIME_ZONE': None, 'USER': '', 'AUTOCOMMIT': True, 'CONN_MAX_AGE': 0, 'OPTIONS': {}, 'PORT': '', 'TEST': {'CHARSET': None, 'MIRROR': None, 'NAME': None, 'COLLATION': None}, 'ENGINE': 'django.db.backends.dummy', 'ATOMIC_REQUESTS': False}}
该命令仍然完全如上所述。我已经看到默认数据库在网站运行时自动填充,但它似乎忽略了我传入的任何密码。也许路由器需要一些调整,但我不知道如何处理它。
答案 0 :(得分:0)
注意堆栈跟踪中的这些行:
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/core/management/commands/migrate.py", line 227, in handle
self.verbosity, self.interactive, connection.alias, apps=post_migrate_apps, plan=plan,
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/core/management/sql.py", line 53, in emit_post_migrate_signal
**kwargs
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/dispatch/dispatcher.py", line 193, in send
for receiver in self._live_receivers(sender)
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/lib/python3.5/site-packages/django/dispatch/dispatcher.py", line 193, in <listcomp>
for receiver in self._live_receivers(sender)
File "/mnt/c/cygwin64/home/chrisb/smart/python/MOC/MOC/material/frontend/apps.py", line 158, in update_modules
_, created = DbModule.objects.get_or_create(label=module.label)
显然,有post_migrate
信号试图使用DbModule
conf创建settings.DATBASE['default']
实例。
导致django.core.exceptions.ImproperlyConfigured
。