【问题标题】:pymongo 3.2: ConnectionFailure not workingpymongo 3.2:连接失败不起作用
【发布时间】:2016-03-18 13:21:54
【问题描述】:

当代码无法连接到 MongoD 实例时,我正在努力让 pymongo 出错。似乎无论我做什么,“pymongo.errors.ConnectionFailure”都不起作用。我已经在 localhost 和远程 mongoD 实例上尝试过这个。当我使用同一系统中的 mongoclient shell('mongo --host xx.xx.xx.xx')时,我得到了正确的“连接被拒绝”。其他例外情况正常,但不是“ConnectionFailure”。请注意,当我在 mongod 实例主机上运行 tshark 嗅探器时,我在关闭的端口上看到正确的 TCP RST 连接被拒绝。 Mongod 没有监听,但是 pymongo ConnectionFailure 无法捕获失败的连接。

python 版本:2.7.10 pymongo 版本:3.2

我可能会遗漏什么,或排除故障的步骤?在下面的示例中,mongod 未在 localhost 上运行。我也在远程主机上停止它。在这两种情况下,都没有捕获到异常错误,并且 pymongo 代码似乎认为它已连接。

代码:

import pymongo
try:
    pymongo.MongoClient('localhost:27017')
except pymongo.errors.ConnectionFailure, e:
    print "Could not connect: %s" % e

【问题讨论】:

  • 你可以使用mongo shell 连接到 MongoDB 吗?
  • 不,响应是连接被拒绝。
  • 所以首先你应该确保 MongoDB 运行正常...
  • mongod 不应该运行。 pymongo 代码没有捕获 ConnectionFailure 的异常。不知道我还能检查什么,因为 MongoD 不应该运行。
  • 我可以让 mongo shell 和 pymongo 正常连接。我认为你没有理解我的问题。就是当它没有运行时,代码无法检测到连接失败。我需要这个的原因是对失败的连接进行详细而精细的检测。

标签: python pymongo


【解决方案1】:

第一次尝试:语法错误

您的代码中有语法错误。变化:

pymongo.MongoClient('localhost':27017)

进入:

pymongo.MongoClient('localhost:27017')

或类似的东西:

pymongo.MongoClient(host='localhost', port=27017)

单引号放错地方了。


使用 Python 3.4.3 和 pymongo 2.9 的工作示例 sn-p

import pymongo

try:
    pymongo.MongoClient('localhost:27017')
except pymongo.errors.ConnectionFailure as e:
    print(e)

看完Pymongo3 migration guide

我认为这种行为是符合要求的,因为guide 告诉:

在 PyMongo 3 中,MongoClient 构造函数不再阻塞,而 连接到服务器或服务器,它不再引发 ConnectionFailure 如果它们不可用,ConfigurationError 如果它们不可用 用户的凭据错误。相反,构造函数返回 立即并在后台线程上启动连接过程。 增加了connect选项来控制这些线程是否 立即启动,或者在第一次使用客户端时启动。

如迁移指南中所示,这样的东西应该可以工作:

from pymongo.errors import ConnectionFailure
client = MongoClient(connect=False)
try:
    result = client.admin.command("ismaster")
except ConnectionFailure:
    print("Server not available")

【讨论】:

  • 该死,这并不能解决问题。我希望它做到了。唯一的区别是你运行的是 Python 3.4.3 而我运行的是 2.7。你是说你得到了 ConnectionFailure 响应,还是它确实连接了?
  • 我既可以连接到端口 27017 上正在运行的数据库,也可以在尝试连接端口 12345 时处理 ConnectionFailure。
  • 好了,进展到这里了,不过还是不明白。这段代码确实有效。当我将句柄添加到数据库并尝试进行身份验证时,似乎 ConnectionFailure 仅适用于我。这有效:
  • @albert感谢您的测试。你运行的是什么版本的 pymongo 和 python?我猜你已经完成了我的代码正确的完整性检查,一定是别的东西。
  • 我的错,你在上面说过。以为你是一个不同的用户。那么我唯一能想到的就是尝试使用 Python 3.4 而不是 2.7。如果您看到我的其他答案,那么我就可以进行 ConnectionFailure 了,但前提是我获得了数据库并尝试进行身份验证。
【解决方案2】:

这似乎只有在我添加两行来获取数据库并进行身份验证时才有效。我不知道为什么。 ConnectionFailure 不应该仅在您尝试连接时捕获错误吗?

try:
    dbconn = pymongo.MongoClient(host, port)
    db = dbconn[dbname]
    success = db.authenticate(user, password)

except pymongo.errors.ConnectionFailure as msg:
    print "Failed connection: %s" % str(msg)

当我在未运行 mongod 的主机上使用嗅探器查看此内容时,它会尝试连接 20-30 秒,然后 pymongo 主机打印:

'连接失败:host.db.com:27017:[Errno 61] 连接被拒绝'

【讨论】:

    【解决方案3】:
    def dbConnect():
        try:
            conn = pymongo.MongoClient(<connection URL>)
            try:
                conn.server_info()
                return "Connection Successfull"
            except OperationFailure as e:
                return e
        except Exception as e:
            return e
    
    print (dbConnect())
    

    由于 MongoClient 没有返回可以帮助处于连接状态的有价值的响应,因此它可以正常工作。

    【讨论】:

      【解决方案4】:

      我在使用pymongo.MongoClient()时也遇到了这个问题。

      试试下面的代码,它可能对你有帮助:

      def initiateDbConnection():
              try:
                  dbConnection= pymongo.MongoClient(<connection URL>)
                  try:
                      dbConnection.server_info()
                      return "Connection Established"
                  except OperationFailure as err:
                      return err
              except Exception as err:
                  return err
          print (initiateDbConnection())
      

      【讨论】:

        【解决方案5】:

        对于那些未来的人,经过一天的故障排除,这就是我们解决此错误问题的方法

        我有一个 Flask 项目,使用 Python 3.9.6、pymongo 3.12.0、flask 2.0.1 和 flask-pymongo 2.3.0 连接到 MongoDb。

        我的连接字符串如下所示:mongodb+srv://my_username:my_user@cluster0.abc123.mongodb.net/my_db_name?retryWrites=true&amp;w=majority

        我在app.py 中的连接初始化如下所示:

            app.config["MONGO_URI"] = "mongodb+srv://my_username:my_user@cluster0.abc123.mongodb.net/my_db_name?retryWrites=true&w=majority"
            mongo = PyMongo(app)
            db = mongo.db
            print("db initialization complete")
        

        在尝试读取或写入数据库但未成功但未收到错误后,我添加了一个 try/except ,如下所示:

        try:
                    myCollection = db["collectionName"]
                    result = myCollection.find({}) # returns all documents
                    print("after query", result)
                    print("after query, again", list(result))
                except Exception as err:
                    print("Error in query_db -> ", err)
        

        然后我能够看到正在发生的错误。由于连接失败而超时。

        Error in query_db -> cluster0.nt7lk.mongodb.net:27017: [Errno 11001] getaddrinfo failed, Timeout: 30s, Topology Description: <TopologyDescription id: 6124a7768a437d2f7c01cdcf, topology_type: Single, servers: [<ServerDescription ('cluster0.nt7lk.mongodb.net', 27017) server_type: Unknown, rtt: None, error=AutoReconnect('cluster0.nt7lk.mongodb.net:27017: [Errno 11001] getaddrinfo failed')>]>
        

        又花了一个小时试图弄清楚这一点,包括检查 Mongo Compass 门户网站上打开的 IP 地址和端口,确保连接字符串来自“通过应用程序连接”而不是“通过 Mongo Compass 连接”,以及一千种定义初始化的方法,我意识到我需要 dnspython 包才能使用其中包含 srv 的 mongo 连接字符串。

        运行pip install -r dnspython进行安装。

        【讨论】:

          猜你喜欢
          • 2017-12-19
          • 1970-01-01
          • 2016-02-21
          • 2019-01-27
          • 2018-10-10
          • 1970-01-01
          • 2013-09-13
          • 1970-01-01
          • 2023-01-19
          相关资源
          最近更新 更多