djongo,无法连接到 cloud.mongodb.com 上的远程数据库

Posted

技术标签:

【中文标题】djongo,无法连接到 cloud.mongodb.com 上的远程数据库【英文标题】:djongo, unable to connect to remote db on cloud.mongodb.com 【发布时间】:2020-09-23 08:18:46 【问题描述】:

我认为以下设置适用于 djongo 连接到 mongodb.com 上的远程 mongodb,但是错误消息显示它仍在尝试连接到 localhost

DATABASES = 
    'default': 
        'ENGINE': 'djongo',
        'HOST': 'mongodb+srv://<username>:<password>@cluster-name/<dbname>?retryWrites=true&w=majority',

下面是错误回溯

Traceback (most recent call last):
  File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "venv/lib/python3.6/site-packages/django/utils/autoreload.py", line 54, in wrapper
    fn(*args, **kwargs)
  File "venv/lib/python3.6/site-packages/django/core/management/commands/runserver.py", line 120, in inner_run
    self.check_migrations()
  File "venv/lib/python3.6/site-packages/django/core/management/base.py", line 453, in check_migrations
    executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
  File "venv/lib/python3.6/site-packages/django/db/migrations/executor.py", line 18, in __init__
    self.loader = MigrationLoader(self.connection)
  File "venv/lib/python3.6/site-packages/django/db/migrations/loader.py", line 49, in __init__
    self.build_graph()
  File "venv/lib/python3.6/site-packages/django/db/migrations/loader.py", line 212, in build_graph
    self.applied_migrations = recorder.applied_migrations()
  File "venv/lib/python3.6/site-packages/django/db/migrations/recorder.py", line 73, in applied_migrations
    if self.has_table():
  File "venv/lib/python3.6/site-packages/django/db/migrations/recorder.py", line 56, in has_table
    return self.Migration._meta.db_table in self.connection.introspection.table_names(self.connection.cursor())
  File "venv/lib/python3.6/site-packages/django/db/backends/base/introspection.py", line 48, in table_names
    return get_names(cursor)
  File "venv/lib/python3.6/site-packages/django/db/backends/base/introspection.py", line 43, in get_names
    return sorted(ti.name for ti in self.get_table_list(cursor)
  File "venv/lib/python3.6/site-packages/djongo/introspection.py", line 47, in get_table_list
    for c in cursor.db_conn.list_collection_names()
  File "venv/lib/python3.6/site-packages/pymongo/database.py", line 856, in list_collection_names
    for result in self.list_collections(session=session, **kwargs)]
  File "venv/lib/python3.6/site-packages/pymongo/database.py", line 819, in list_collections
    _cmd, read_pref, session)
  File "venv/lib/python3.6/site-packages/pymongo/mongo_client.py", line 1454, in _retryable_read
    read_pref, session, address=address)
  File "venv/lib/python3.6/site-packages/pymongo/mongo_client.py", line 1253, in _select_server
    server = topology.select_server(server_selector)
  File "venv/lib/python3.6/site-packages/pymongo/topology.py", line 235, in select_server
    address))
  File "venv/lib/python3.6/site-packages/pymongo/topology.py", line 193, in select_servers
    selector, server_timeout, address)
  File "venv/lib/python3.6/site-packages/pymongo/topology.py", line 209, in _select_servers_loop
    self._error_message(selector))
pymongo.errors.ServerSelectionTimeoutError: localhost:27017: [Errno 111] Connection refused

【问题讨论】:

【参考方案1】:

我以前遇到过你的问题。就我而言,我在容器中运行 django 和 mongodb。而且我发现无论我在setting.py 中设置什么设置,djongo(他们在后面使用 pymongo)都会忽略我的设置。

对于寻求解决方案的其他人,您可能需要检查setting.py 中的语法,应该如下所示:

 DATABASES = 
        'default': 
            'ENGINE': 'djongo',
            'NAME': 'your-db-name',
            'ENFORCE_SCHEMA': False,
            'CLIENT': 
                'host': 'host-name or ip address',
                'port': port_number,
                'username': 'db-username',
                'password': 'password',
                'authSource': 'db-name',
                'authMechanism': 'SCRAM-SHA-1'
            ,

         .......

Detail from djongo document

你可以看到主机、用户、密码字段都在 'CLIENT' 下,这与 Django 描述的默认语法不同。所以也许大多数人在这里感到困惑并陷入这个问题。

【讨论】:

【参考方案2】:

转到 settings.py 文件并使用下面的数据库设置

DATABASES = 
    'default': 
        'ENGINE': 'djongo',
        'ENFORCE_SCHEMA': True
        'NAME': 'your-db-name',
        'HOST': 'host-name or ip address',
        'PORT': port_number,
        'USER': 'db-username',
        'PASSWORD': 'password',
        'AUTH_SOURCE': 'db-name',
        'AUTH_MECHANISM': 'SCRAM-SHA-1',
    

还请查看这篇文章以了解 django 和 mongo db 之间的连接。

https://medium.com/@ksarthak4ever/how-to-use-django-with-mongodb-40ba36a21124

我个人建议你请使用pycharm。在 Pycharm 中,您可以测试您的连接。以便您更清晰地了解整个场景。

我在 django 中使用远程数据库。你可以在下面的图片中看到

【讨论】:

谢谢,我应该为 DATABASES 对象中的 'AUTH_SOURCE' 键添加什么 不客气!听起来不错,您的问题已解决。【参考方案3】:

我找到了解决方案

我采用了以下方法>

所以,djongo 在幕后使用 -> pymongo

而pymongo的默认配置是

class MongoClient(common.BaseObject):
    HOST = "localhost"   # here HOST has the hardcoded value
    PORT = 27017      

位于以下文件中

venv/lib/python3.6/site-packages/pymongo/mongo_client.py

将 HOST 的硬编码值替换为

HOST = 'mongodb+srv://<username>:<password>@cluster-name/<dbname>?retryWrites=true&w=majority'

额外 我们可以根据需要设置环境变量

HOST = os.getenv('MONGO_DB_URL')

【讨论】:

以上是关于djongo,无法连接到 cloud.mongodb.com 上的远程数据库的主要内容,如果未能解决你的问题,请参考以下文章

Djongo 没有连接到 mlab 服务器

Djongo数据库引擎上的Django Admin外键错误

Django 总是连接到 localhost mongodb

Djongo 没有使用 Django-rest-framework 正确获取对象数组嵌入字段

如何将Django ORM连接到mongo atlas?

Django - 无法使用两个数据库进行测试(带有 gis 扩展的 postgres 和 mongoDB (Djongo)