Django 无法连接到 mongoDB 地图集

Posted

技术标签:

【中文标题】Django 无法连接到 mongoDB 地图集【英文标题】:Django cant connect to mongoDB atlas 【发布时间】:2020-06-05 10:41:11 【问题描述】:

最近我开始了一个项目,使用 Django 后端和托管在其 Atlas 平台上的 mongoDB 数据库制作 Web 服务器,因此我不必担心在本地运行它。

我还处于设置的早期阶段,遇到了这个错误:

pymongo.errors.ServerSelectionTimeoutError: localhost:27017: [WinError 10061] No connection could be made because the target machine actively refused it

可能还需要提及的是,我目前在数据库或模型上没有 Django 应用程序形式的文档,但我怀疑这是问题,因为当我运行 manage.py migrate 时,我得到了上述错误,而不是“没有带有标签的应用”错误。

我的 settings.py 中的数据库配置目前如下所示:

DATABASES = 
    'default': 
        'ENGINE': 'djongo',
        'NAME': 'house-project',
        'HOST': 'mongodb+srv://<my-user-name>:<my-password>@house-project-9g5fo.gcp.mongodb.net/test?retryWrites=true&w=majority'
    

我知道常见的错误之一是您的密码和用户名中有特殊字符,我已确保不包含任何字符或使用十六进制字符转义它们。我已确保在 Atlas 端添加我的 ip 和用户。我在网上查了一个现有的答案,但无济于事。我发现的最接近的问题是:How to connect Django ORM to mongo atlas?,但遗憾的是,这个解决方案对我不起作用。

在尝试解决此问题时,任何帮助都会非常有用,如果需要有关我的设置的任何其他信息,请告诉我,我很乐意提供。我还包括了一个堆栈跟踪,以防它在下面相关。

Traceback (most recent call last):
  File "manage.py", line 20, in <module>
    main()
  File "manage.py", line 16, in main
    execute_from_command_line(sys.argv)
  File "C:\Users\mkars\.virtualenvs\house-project-VuTUb3qx\lib\site-packages\django\core\management\__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "C:\Users\mkars\.virtualenvs\house-project-VuTUb3qx\lib\site-packages\django\core\management\__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "C:\Users\mkars\.virtualenvs\house-project-VuTUb3qx\lib\site-packages\django\core\management\base.py", line 323, in run_from_argv
    self.execute(*args, **cmd_options)
  File "C:\Users\mkars\.virtualenvs\house-project-VuTUb3qx\lib\site-packages\django\core\management\base.py", line 364, in execute
    output = self.handle(*args, **options)
  File "C:\Users\mkars\.virtualenvs\house-project-VuTUb3qx\lib\site-packages\django\core\management\base.py", line 83, in wrapped
    res = handle_func(*args, **kwargs)
  File "C:\Users\mkars\.virtualenvs\house-project-VuTUb3qx\lib\site-packages\django\core\management\commands\migrate.py", line 87, in handle
    executor = MigrationExecutor(connection, self.migration_progress_callback)
  File "C:\Users\mkars\.virtualenvs\house-project-VuTUb3qx\lib\site-packages\django\db\migrations\executor.py", line 18, in __init__
    self.loader = MigrationLoader(self.connection)
  File "C:\Users\mkars\.virtualenvs\house-project-VuTUb3qx\lib\site-packages\django\db\migrations\loader.py", line 49, in __init__
    self.build_graph()
  File "C:\Users\mkars\.virtualenvs\house-project-VuTUb3qx\lib\site-packages\django\db\migrations\loader.py", line 212, in build_graph
    self.applied_migrations = recorder.applied_migrations()
  File "C:\Users\mkars\.virtualenvs\house-project-VuTUb3qx\lib\site-packages\django\db\migrations\recorder.py", line 73, in applied_migrations
    if self.has_table():
  File "C:\Users\mkars\.virtualenvs\house-project-VuTUb3qx\lib\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 "C:\Users\mkars\.virtualenvs\house-project-VuTUb3qx\lib\site-packages\django\db\backends\base\introspection.py", line 48, in table_names
    return get_names(cursor)
  File "C:\Users\mkars\.virtualenvs\house-project-VuTUb3qx\lib\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 "C:\Users\mkars\.virtualenvs\house-project-VuTUb3qx\lib\site-packages\djongo\introspection.py", line 47, in get_table_list
    for c in cursor.db_conn.list_collection_names()
  File "C:\Users\mkars\.virtualenvs\house-project-VuTUb3qx\lib\site-packages\pymongo\database.py", line 856, in list_collection_names
    for result in self.list_collections(session=session, **kwargs)]
  File "C:\Users\mkars\.virtualenvs\house-project-VuTUb3qx\lib\site-packages\pymongo\database.py", line 818, in list_collections
    return self.__client._retryable_read(
  File "C:\Users\mkars\.virtualenvs\house-project-VuTUb3qx\lib\site-packages\pymongo\mongo_client.py", line 1453, in _retryable_read
    server = self._select_server(
  File "C:\Users\mkars\.virtualenvs\house-project-VuTUb3qx\lib\site-packages\pymongo\mongo_client.py", line 1253, in _select_server
    server = topology.select_server(server_selector)
  File "C:\Users\mkars\.virtualenvs\house-project-VuTUb3qx\lib\site-packages\pymongo\topology.py", line 233, in select_server
    return random.choice(self.select_servers(selector,
  File "C:\Users\mkars\.virtualenvs\house-project-VuTUb3qx\lib\site-packages\pymongo\topology.py", line 192, in select_servers
    server_descriptions = self._select_servers_loop(
  File "C:\Users\mkars\.virtualenvs\house-project-VuTUb3qx\lib\site-packages\pymongo\topology.py", line 208, in _select_servers_loop
    raise ServerSelectionTimeoutError(
pymongo.errors.ServerSelectionTimeoutError: localhost:27017: [WinError 10061] No connection could be made because the target machine actively refused it```

【问题讨论】:

这个文本“localhost:27017”让我觉得连接配置没有被正确拾取。显然它并没有尝试连接到“house-project-9g5fo.gcp.mongodb.net”。可以尝试编写一个简短的 python 脚本,并在脚本本身中配置连接,并使其工作? 你在某种程度上是正确的。我按照您的建议做了,并仅使用 pymongo 在单独的实例中测试了连接,并建立了连接,我可以毫无问题地将项目推送到数据库。我仍然不知道是什么导致了 Django 中的这个问题。如果你有什么我可以尝试的,那将不胜感激。 我不知道 Django。您的代码是否有可能没有获取最新/修改版本的 settings.py?是否可以打印配置参数? ***.com/questions/6369697/… 【参考方案1】:

Djongo 文档不正确或过时。我能够使用以下设置让我的 Django 应用程序连接到 mongodb:

DATABASES = 
    'default': 
        'ENGINE': 'djongo',
        'CLIENT': 
            'host': 'mongodb+srv://<URL>',
            'username': 'something',
            'password': 'somepass',
            'authMechanism': 'SCRAM-SHA-1'
        
    

【讨论】:

【参考方案2】:

同样的问题。这确实是一种非常 hacky 的方式来修改库设置以达到预期的结果。问题可能源于两个地方:要么来自 Djongo 引擎(很可能),它没有将指定的 HOST 转发到 pymongo 的 mongo_client.py 构造函数。另一个来源可能是 Django 本身,它没有以正确的方式调用构造函数(不太可能)。我想将我的项目部署到 Heroku,但这是不可能的,因为我安装的所有依赖项都会有这个错误,我无法手动更改 HOST 名称。

【讨论】:

【参考方案3】:

我找到了一个非常老套的解决方案。 Jayadevan 是正确的,pymongo 试图连接到我的本地主机而不是提供的 URI,尽管我指定了主机。

我一直在寻找为什么会这样,我偶然发现了this github 问题。在这个线程中有一个建议更改 mongo_client.py 中的主机。这个文件可以在你的依赖文件所在的目录中找到。

更改此文件中的主机确实允许我的数据库连接。这使我相信 pymongo 没有考虑您指定的主机。

如果有人知道我错过了什么,或者我可以修复当前设置以便我不必使用此解决方法,请告诉我。

【讨论】:

我已经尝试过该 Github 链接的解决方案。我发现无论您在 mongo_client.py 中使用不同名称提供什么 URL 或 DB 名称,它都只会从 settings.py 中获取名称。在 mongo_client.py 我给了 HOST = "mongodb+srv://*un*:*pwd*@cluster0/ebookstore5?retryWrites=true&w=majority" PORT = 27017 并在 settings.py 和 ecostore91 之后对我来说它正在创建本地数据库 ebookstore91 但不在 atlas 或 ebookstore5 中,因为我在 mongo_client.py 中给出了

以上是关于Django 无法连接到 mongoDB 地图集的主要内容,如果未能解决你的问题,请参考以下文章

无法连接到 mongoDB 图集

django 连接到 mysql 和 mongodb

Django 总是连接到 localhost mongodb

新手连接 MongoDB 出错求助

Heroku 和 MongoDB 地图集连接

Meteor 无法连接到 MongoDB