代码之家  ›  专栏  ›  技术社区  ›  Plup

连接失败时,PyMongo异步客户端未引发异常

  •  1
  • Plup  · 技术社区  · 6 月前

    当连接出现问题时,pymongo 4.10异步客户端似乎不会引发异常。

    取自 the doc ,一个没有在本地运行任何mongo DB的测试会产生:

    >>> import asyncio
    >>> from pymongo import AsyncMongoClient
    >>> client = AsyncMongoClient('mongodb://localhost:27017/')
    >>> asyncio.run(client.aconnect())
    # no errors
    

    激活调试日志时,我看到连接被拒绝,但我预计会引发异常。

    >>> import logging
    >>> logging.basicConfig(level='DEBUG')
    >>> asyncio.run(client.aconnect())
    DEBUG:asyncio:Using selector: KqueueSelector
    DEBUG:pymongo.topology:{"topologyId": {"$oid": "676020be62e71d3fe6f27721"}, "serverHost": "localhost", "serverPort": 27017, "awaited": false, "durationMS": 2.786167000522255, "failure": "\"AutoReconnect('localhost:27017: [Errno 61] Connection refused (configured timeouts: socketTimeoutMS: 20000.0ms, connectTimeoutMS: 20000.0ms)')\"", "message": "Server heartbeat failed"}
    

    我预计DEBUG日志错误是一个异常。我对异步客户端有什么误解吗?

    1 回复  |  直到 6 月前
        1
  •  2
  •   vaizki    6 月前

    mongo客户端在后台使用连接池等,即使你告诉它显式连接(为什么?),它也不会因连接失败而引发异常,直到你真正尝试从数据库读取或向数据库写入。

    但你可以检查它是否/在哪里连接:

    >>> list(client.nodes)
    [('10.0.0.1', 27017)]
    

    如果满足以下条件,结果将为空列表 aconnect 失败。

    但是,如果您尝试任何通信,例如:

    >>> await client.server_info()
    

    …你会得到一个例外:

    pymongo.errors.ServerSelectionTimeoutError: localhost:27017: [Errno 111] Connection refused (configured timeouts: socketTimeoutMS: 20000.0ms, connectTimeoutMS: 20000.0ms), Timeout: 1.9985503089847043s, Topology Description: <TopologyDescription id: 6760281eda9a9980ea35e425, topology_type: Unknown, servers: [<ServerDescription ('localhost', 27017) server_type: Unknown, rtt: None, error=AutoReconnect('localhost:27017: [Errno 111] Connection refused (configured timeouts: socketTimeoutMS: 20000.0ms, connectTimeoutMS: 20000.0ms)')>]>
    

    pymongo异步驱动程序就是这样构建的。。为什么教程告诉你使用 aconnect() …我不知道。我甚至不知道它的存在。

    顺便说一句,你可以使用 python -m async 获取一个REPL,您可以在其中运行异步命令,而无需 asyncio.run()