在数据库路由器内部的迁移命令django中访问指定的数据库
Accessing specified database in migrate command django inside database router
使用 Django 1.11,我正在尝试创建一个自定义路由器,以根据使用的 URL 选择一个数据库。
例如,如果 URL 是 customer1.example.com,我想选择数据库 'customer1',同样如果它是 customer2.example.com,我希望它选择数据库 'customer2'
我当前的设置效果很好!一个问题 - 当我尝试 运行 迁移(或其他依赖数据库的命令)时,它会失败 - 即使我使用 --database 选项指定数据库,例如 python manage.py migrate --database customer1
我不确定该怎么做,因为没有这些要求 - 我实际上想 return 在命令行中指定的确切名称(例如 customer1)。但它不是提示,也不是任何其他选项。如何访问用于 运行 命令的命令行选项?不然我也没什么好return!
这是我的设置:
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
我觉得 returns "whatever the --database option was in the command" 的 except 块中应该有一些东西 - 但我找不到访问它的方法。有什么建议吗?
这是我尝试 运行 命令时的输出: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}}
命令仍然完全按照我上面的描述失败。我已经看到默认数据库在站点 运行ning 时自动填充,但它似乎忽略了我输入的任何密码。也许路由器需要一些调整,但我不知道如何处理它。
注意堆栈跟踪中的这些行:
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
信号试图使用 settings.DATBASE['default']
conf 创建一个 DbModule
实例。
这导致了 django.core.exceptions.ImproperlyConfigured
。
使用 Django 1.11,我正在尝试创建一个自定义路由器,以根据使用的 URL 选择一个数据库。
例如,如果 URL 是 customer1.example.com,我想选择数据库 'customer1',同样如果它是 customer2.example.com,我希望它选择数据库 'customer2'
我当前的设置效果很好!一个问题 - 当我尝试 运行 迁移(或其他依赖数据库的命令)时,它会失败 - 即使我使用 --database 选项指定数据库,例如 python manage.py migrate --database customer1
我不确定该怎么做,因为没有这些要求 - 我实际上想 return 在命令行中指定的确切名称(例如 customer1)。但它不是提示,也不是任何其他选项。如何访问用于 运行 命令的命令行选项?不然我也没什么好return!
这是我的设置:
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
我觉得 returns "whatever the --database option was in the command" 的 except 块中应该有一些东西 - 但我找不到访问它的方法。有什么建议吗?
这是我尝试 运行 命令时的输出: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}}
命令仍然完全按照我上面的描述失败。我已经看到默认数据库在站点 运行ning 时自动填充,但它似乎忽略了我输入的任何密码。也许路由器需要一些调整,但我不知道如何处理它。
注意堆栈跟踪中的这些行:
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
信号试图使用 settings.DATBASE['default']
conf 创建一个 DbModule
实例。
这导致了 django.core.exceptions.ImproperlyConfigured
。