Mongo + Postgres + Django 测试错误 - 多数据库 (Django-MongoDB-Engine)
我一直在尝试让我的Django测试正常工作,因为我正在构建一个API。我对Python还比较陌生,所以在这方面卡了很久。
这里有一些简单的情况:
- 我使用了两个数据库——一个是PostgreSQL数据库用来存储用户信息,另一个是MongoDB用来存储其他所有数据。
- 我使用了TastyPie、Django-MongoDB-Engine、Djangotoolbox、Django-Non-rel、Pymongo和psycopg2这些工具。
- 我已经成功连接了这两个数据库。当我在命令行中保存一个auth_user时,它会保存到SQL数据库,而我应用中的模型则会保存到MongoDB。
我需要把这个和另一个API整合在一起,所以在选择数据库和库的时候受到了限制。
我最大的问题就是测试——我无法让它正常工作。
每当我尝试用命令./manage.py test运行Django的测试时,总是出现这个错误:
pymongo.errors.OperationFailure: command SON([('authenticate', 1), ('user', u'test'), ('nonce', u'blahblah'), ('key', u'blahblah')]) failed: auth fails
经过大量搜索,我仍然不确定问题出在哪里。我知道显然是有东西在尝试与我的MongoDB进行身份验证,但它没有成功。我不介意使用这个数据库进行测试,反正它就是一个测试数据库。
请帮帮我!我的配置和错误信息在下面。
我设置了数据库配置,包括了两个数据库,如下所示:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'main_db',
'USER': os.environ['RDS_USERNAME'],
'PASSWORD': os.environ['RDS_PASSWORD'],
'HOST': os.environ['RDS_HOSTNAME'],
'PORT': os.environ['RDS_PORT'],
},
'mongo': {
'ENGINE': 'django_mongodb_engine',
'NAME': 'mongo_db',
'USER': os.environ['MONGO_USERNAME'],
'PASSWORD': os.environ['MONGO_PASSWORD'],
'HOST': os.environ['MONGO_HOSTNAME'],
'PORT': os.environ['MONGO_PORT'],
}
}
DATABASE_ROUTERS = ['myproject.database_router.AuthRouter']
正如你所看到的,我创建了自己的自定义路由:
sql_databases = ['admin', 'auth', 'contenttypes', 'tastypie'
'sessions', 'messages', 'staticfiles']
class AuthRouter(object):
"""
A router to control all database operations on models in the
auth application.
"""
def db_for_read(self, model, **hints):
"""
Attempts to read auth models go to auth_db.
"""
if model._meta.app_label in sql_databases:
return 'default'
return 'mongo'
def db_for_write(self, model, **hints):
"""
Attempts to write auth models go to auth_db.
"""
if model._meta.app_label in sql_databases:
return 'default'
return 'mongo'
def allow_relation(self, obj1, obj2, **hints):
"""
Allow relations only if model does includes auth app.
"""
if obj1._meta.app_label in sql_databases or \
obj2._meta.app_label in sql_databases:
return True
return False
def allow_migrate(self, db, model):
"""
Make sure the auth app only appears in the 'auth_db'
database.
"""
if db == 'default':
return model._meta.app_label in sql_databases
elif model._meta.app_label in sql_databases:
return False
return False
完整的错误追踪信息在这里:
Traceback (most recent call last):
File "./manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "myproject/djenv/lib/python2.7/site-packages/django/core/management/__init__.py", line 399, in execute_from_command_line
utility.execute()
File "myproject/djenv/lib/python2.7/site-packages/django/core/management/__init__.py", line 392, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "myproject/djenv/lib/python2.7/site-packages/django/core/management/commands/test.py", line 50, in run_from_argv
super(Command, self).run_from_argv(argv)
File "myproject/djenv/lib/python2.7/site-packages/django/core/management/base.py", line 242, in run_from_argv
self.execute(*args, **options.__dict__)
File "myproject/djenv/lib/python2.7/site-packages/django/core/management/commands/test.py", line 71, in execute
super(Command, self).execute(*args, **options)
File "myproject/djenv/lib/python2.7/site-packages/django/core/management/base.py", line 285, in execute
output = self.handle(*args, **options)
File "myproject/djenv/lib/python2.7/site-packages/django/core/management/commands/test.py", line 88, in handle
failures = test_runner.run_tests(test_labels)
File "myproject/djenv/lib/python2.7/site-packages/django/test/runner.py", line 145, in run_tests
old_config = self.setup_databases()
File "myproject/djenv/lib/python2.7/site-packages/django/test/runner.py", line 107, in setup_databases
return setup_databases(self.verbosity, self.interactive, **kwargs)
File "myproject/djenv/lib/python2.7/site-packages/django/test/runner.py", line 279, in setup_databases
verbosity, autoclobber=not interactive)
File "myproject/djenv/lib/python2.7/site-packages/django_mongodb_engine/creation.py", line 196, in create_test_db
self.connection._reconnect()
File "myproject/djenv/lib/python2.7/site-packages/django_mongodb_engine/base.py", line 279, in _reconnect
self._connect()
File "myproject/djenv/lib/python2.7/site-packages/django_mongodb_engine/base.py", line 268, in _connect
if not self.database.authenticate(user, password):
File "myproject/djenv/lib/python2.7/site-packages/pymongo/database.py", line 891, in authenticate
self.connection._cache_credentials(self.name, credentials)
File "myproject/djenv/lib/python2.7/site-packages/pymongo/mongo_client.py", line 459, in _cache_credentials
auth.authenticate(credentials, sock_info, self.__simple_command)
File "myproject/djenv/lib/python2.7/site-packages/pymongo/auth.py", line 243, in authenticate
auth_func(credentials[1:], sock_info, cmd_func)
File "myproject/djenv/lib/python2.7/site-packages/pymongo/auth.py", line 222, in _authenticate_mongo_cr
cmd_func(sock_info, source, query)
File "myproject/djenv/lib/python2.7/site-packages/pymongo/mongo_client.py", line 690, in __simple_command
helpers._check_command_response(response, None, msg)
File "myproject/djenv/lib/python2.7/site-packages/pymongo/helpers.py", line 178, in _check_command_response
raise OperationFailure(msg % errmsg, code, response)
pymongo.errors.OperationFailure: command SON([('authenticate', 1), ('user', u'test'), ('nonce', u'blahblah'), ('key', u'blahblah')]) failed: auth fails
任何帮助都非常感谢!
1 个回答
0
想给大家更新一下我是怎么解决这个问题的 - 我原以为是读写的问题(和认证失败有关),但其实不是。
如果你看到这个错误,那就是认证问题 - 可能是你的用户名、密码、数据库名或者集合名不正确。
pymongo.errors.OperationFailure: command SON([('authenticate', 1), ('user', u'test'), ('nonce', u'blahblah'), ('key', u'blahblah')]) failed: auth fails
Django在设置测试数据库时,会在数据库名的前面加上'test_'。所以我主要的数据库叫maindb,测试数据库就变成'test_maindb'了。
你可以在这里查看相关信息:测试数据库和Django
确保你可以向一个名为你的数据库名加上'test_'的独立数据库写入数据。
另外,还有一种解决方案是直接在你的数据库设置中定义测试数据库的设置。你可以通过在任何数据库属性后面加上'TEST_'来实现。比如:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'maindb', 'USER': os.environ['RDS_USERNAME'], 'PASSWORD': os.environ['RDS_PASSWORD'], 'HOST': os.environ['RDS_HOSTNAME'], 'PORT': os.environ['RDS_PORT'], 'TEST_NAME': 'my_test_sql', 'TEST_USER': 'test_sql_user', 'TEST_PASSWORD': 'password' }, 'mongo': { 'ENGINE': 'django_mongodb_engine', 'NAME': 'mongodb', 'USER': os.environ['MONGO_USERNAME'], 'PASSWORD': os.environ['MONGO_PASSWORD'], 'HOST': os.environ['MONGO_HOSTNAME'], 'PORT': os.environ['MONGO_PORT'], 'TEST_NAME': 'my_test_mongodb', 'TEST_USER': 'test_mongo_user', 'TEST_PASSWORD': 'password' } }
希望这能帮到你!如果你有其他想法,请反馈给我。