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

djongo, unable to connect to remote db on cloud.mongodb.com

我认为下面的设置可以让 djongo 在 mongodb.com 上连接到远程 mongodb 但是,错误消息显示它仍在尝试连接到本地主机

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

转到 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 数据库之间的连接。

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

我个人推荐你使用pycharm。在 Pycharm 您可以测试您的连接。这样您就可以更清楚地了解整个场景。

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

我找到了解决方案

我采用了以下方法>

所以,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')

我以前遇到过你的问题。就我而言,我 运行 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描述的默认语法不同。所以也许大多数人在这里会感到困惑并卡在这个问题上。