在数据库路由器内的migrate命令django中访问指定的数据库

时间:2018-05-07 21:40:53

标签: django python-3.x django-1.11

使用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}}

该命令仍然完全如上所述。我已经看到默认数据库在网站运行时自动填充,但它似乎忽略了我传入的任何密码。也许路由器需要一些调整,但我不知道如何处理它。

1 个答案:

答案 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