如何检查MongoDB实例的客户端是否有效?

Lee*_*ren 37 python mongodb pymongo

特别是,我目前正在尝试使用以下函数检查与客户端的连接是否有效:

def mongodb_connect(client_uri):
    try:
        return pymongo.MongoClient(client_uri)
    except pymongo.errors.ConnectionFailure:
         print "Failed to connect to server {}".format(client_uri)
Run Code Online (Sandbox Code Playgroud)

然后我像这样使用这个函数:

def bucket_summary(self):
    client_uri = "some_client_uri"
    client = mongodb_connect(client_uri)
    db = client[tenant_id]
    ttb = db.timebucket.count() # If I use an invalid URI it hangs here
Run Code Online (Sandbox Code Playgroud)

如果给出了无效的URI,有没有办法在最后一行捕获并抛出异常?我最初认为这就是ConnectionFailure的用途(因此连接时可能会被捕获)但我错了.

如果我使用无效的URI运行程序,该程序无法运行,则发出KeyboardInterrupt会产生:

File "reportjob_status.py", line 58, in <module>
tester.summarize_timebuckets()
File "reportjob_status.py", line 43, in summarize_timebuckets
ttb = db.timebucket.count() #error
File "/Library/Python/2.7/site-packages/pymongo/collection.py", line   1023, in count
return self._count(cmd)
File "/Library/Python/2.7/site-packages/pymongo/collection.py", line 985, in _count
with self._socket_for_reads() as (sock_info, slave_ok):
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/contextlib.py", line 17, in __enter__
return self.gen.next()
File "/Library/Python/2.7/site-packages/pymongo/mongo_client.py", line 699, in _socket_for_reads
with self._get_socket(read_preference) as sock_info:
File  "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/contextlib.py", line 17, in __enter__
return self.gen.next()
File "/Library/Python/2.7/site-packages/pymongo/mongo_client.py", line 663, in _get_socket
server = self._get_topology().select_server(selector)
File "/Library/Python/2.7/site-packages/pymongo/topology.py", line 121, in select_server
address))
File "/Library/Python/2.7/site-packages/pymongo/topology.py", line 106, in select_servers
self._condition.wait(common.MIN_HEARTBEAT_INTERVAL)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 358, in wait
_sleep(delay)
Run Code Online (Sandbox Code Playgroud)

Syl*_*oux 51

serverSelectionTimeoutMS的关键字参数pymongo.mongo_client.MongoClient控制驱动多久尝试连接到服务器.默认值为30秒.

将其设置为与典型连接时间¹兼容的非常低的值,以立即报告错误.您需要在此之后查询数据库以触发连接尝试:

>>> maxSevSelDelay = 1 # Assume 1ms maximum server selection delay
>>> client = pymongo.MongoClient("someInvalidURIOrNonExistantHost",
                                 serverSelectionTimeoutMS=maxSevSelDelay)
//                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>> client.server_info()
Run Code Online (Sandbox Code Playgroud)

这会提高pymongo.errors.ServerSelectionTimeoutError.

¹ 显然设置serverSelectionTimeoutMS0甚至可能会在特定的情况下工作,你的服务器有非常低的延迟("本地"服务器的情况下,用很轻的负载为例)


您应该抓住该异常并正确处理它.这样的东西:

try:
    client = pymongo.MongoClient("someInvalidURIOrNonExistantHost",
                                     serverSelectionTimeoutMS=maxSevSelDelay)
    client.server_info() # force connection on a request as the
                         # connect=True parameter of MongoClient seems
                         # to be useless here 
except pymongo.errors.ServerSelectionTimeoutError as err:
    # do whatever you need
    print(err)
Run Code Online (Sandbox Code Playgroud)

将显示:

No servers found yet
Run Code Online (Sandbox Code Playgroud)


小智 9

嗨,要知道连接是否建立,你可以这样做:

from pymongo import MongoClient
from pymongo.errors import ConnectionFailure
client = MongoClient()
try:
   # The ismaster command is cheap and does not require auth.
   client.admin.command('ismaster')
except ConnectionFailure:
   print("Server not available")
Run Code Online (Sandbox Code Playgroud)

  • 已投票,应该是公认的答案,因为这是[在 MongoClient 类的注释中公布的内容](https://github.com/mongodb/mongo-python-driver/blob/c8d920a46bfb7b054326b3e983943bfc794cb676/pymongo/mongo_client.py# L157-L173)。 (2认同)