pymongo 3.2:ConnectionFailure不起作用

3
我正在尝试使用pymongo连接MongoD实例,但无论我做什么,都似乎无法使'pymongo.errors.ConnectionFailure'发挥作用。我已在本地主机和远程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未在本地主机上运行。我还停止了远程主机上的mongod。在这两种情况下,异常错误未被捕获,而pymongo代码似乎认为它已连接。

代码:

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

你能否使用 mongo shell 连接到 MongoDB? - albert
不,回复是连接被拒绝。 - Robert
所以首先你应该确保MongoDB正常运行... - albert
mongod不应该运行。pymongo代码没有捕获ConnectionFailure异常。不确定还能检查什么,因为MongoD不应该运行。 - Robert
我可以很好地连接mongo shell和pymongo。我认为你没有理解我的问题。问题是当它没有运行时,代码无法检测到连接失败。我需要这个的原因是需要详细和精细地检测连接失败。 - Robert
如果 mongod 没有运行,您就没有数据库实例可以连接。连接到不可用主机上的数据库肯定会引发连接错误... - albert
5个回答

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没有返回有助于连接状态的有价值响应,因此这个方法可以正常工作。

2

我在使用 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())

0

第一次尝试:语法错误

您的代码出现了语法错误。请更改:

pymongo.MongoClient('localhost':27017)

转换为:

pymongo.MongoClient('localhost:27017')

或者类似这样:

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

你把单引号放错了位置。


使用Python 3.4.3和pymongo 2.9的工作示例片段

import pymongo

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

阅读完Pymongo3迁移指南之后

我认为这个行为是期望的,因为指南中提到:

在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的响应,还是连接成功了? - Robert
好的,进展不错,但我仍然不理解。这段代码确实可以工作。看起来只有当我将句柄添加到数据库并尝试进行身份验证时,ConnectionFailure才会起作用。这样就可以工作: - Robert
在pymongo在Python 2.7和3.x之间表现不同的情况下是否存在已知问题? - Robert
我刚在虚拟环境中安装了pymongo 3.2(Python 3.4.3),但连接错误没有被正确捕获。 - albert
很高兴你也没有错过,哈。感谢您提供这宝贵的信息。我在谷歌上搜索时错过了迁移指南。现在我可以调整我的代码以实现非阻塞行为。 - Robert
显示剩余9条评论

0

当我添加两行代码来获取数据库和进行身份验证时,这似乎只有这样才能正常工作。我不知道为什么。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]拒绝连接”。

0

对于未来的读者,这是我们在一天的故障排除后解决此错误的方法。

我有一个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&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 Web Portal上的开放IP地址和端口,确保连接字符串来自“通过应用程序连接”而不是“通过Mongo Compass连接”,以及定义初始化的一千种方式后,我意识到我需要dnspython软件包才能使用包含srv的mongo连接字符串。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接