You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PyMongo连接Azure Cosmos MongoDB无服务器数据库超时求助

问题:无法用pymongo连接Azure Cosmos DB(MongoDB引擎无服务器分片)

问题详情

创建了采用MongoDB引擎的Azure Cosmos DB(RU无服务器分片),尝试通过Python的pymongo库连接查询,但始终无法成功:

  • 已测试MongoDB Server兼容版本3.6和7.0
  • 排除防火墙问题(多网络环境测试)
  • 使用azure-cosmos库可正常连接,但该库不适用于MongoDB引擎场景
  • 尝试过多个pymongo版本,均出现ServerSelectionTimeoutError超时错误

使用的连接字符串格式:

mongodb://{user_name}:{primary_key}@{service_name}.mongo.cosmos.azure.com:10255/?ssl=true&replicaSet=globaldb&retrywrites=false&maxIdleTimeMS=120000&appName=@{service_name}@

测试代码:

import pymongo

CONN_STRING = "mongodb://etc...."  # 替换为实际连接字符串

client = pymongo.MongoClient(CONN_STRING)

client.list_database_names()

报错信息:

{
    "name": "ServerSelectionTimeoutError",
    "message": "{service_name}.mongo.cosmos.azure.com:10255: timed out, Timeout: 30s, Topology Description: <TopologyDescription id: 6734b32d878003e1a30f46fb, topology_type: Single, servers: [<ServerDescription ('{service_name}.mongo.cosmos.azure.com', 10255) server_type: Unknown, rtt: None, error=NetworkTimeout('{service_name}.mongo.cosmos.azure.com:10255: timed out')>]>",
    "stack": "---------------------------------------------------------------------------
ServerSelectionTimeoutError               Traceback (most recent call last)
Cell In[17], line 1
----> 1 client.list_database_names()

File ...\\Lib\\site-packages\\pymongo\\mongo_client.py:1918, in MongoClient.list_database_names(self, session)
   1908 def list_database_names(self, session=None):
   1909     \"\"\"Get a list of the names of all databases on the connected server.
   1910 
   1911     :Parameters:
   (...)
   1915     .. versionadded:: 3.6
   1916     \"\"\"
   1917     return [doc[\"name\"]
-> 1918             for doc in self.list_databases(session, nameOnly=True)]

File ...\\Lib\\site-packages\\pymongo\\mongo_client.py:1899, in MongoClient.list_databases(self, session, **kwargs)
   1897 cmd.update(kwargs)
   1898 admin = self._database_default_options(\"admin\")
-> 1899 res = admin._retryable_read_command(cmd, session=session)
   1900 # listDatabases doesn't return a cursor (yet). Fake one.
   1901 cursor = {
   1902     \"id\": 0,
   1903     \"firstBatch\": res[\"databases\"],
   1904     \"ns\": \"admin.$cmd\",
   1905 }

File ...\\Lib\\site-packages\\pymongo\\database.py:755, in Database._retryable_read_command(self, command, value, check, allowable_errors, read_preference, codec_options, session, **kwargs)
    750 def _cmd(session, server, sock_info, slave_ok):
    751     return self._command(sock_info, command, slave_ok, value,
    752                          check, allowable_errors, read_preference,
    753                          codec_options, session=session, **kwargs)
--> 755 return self.__client._retryable_read(
    756     _cmd, read_preference, session)

File ...\\Lib\\site-packages\\pymongo\\mongo_client.py:1460, in MongoClient._retryable_read(self, func, read_pref, session, address, retryable, exhaust)
   1458 while True:
   1459     try:
-> 1460         server = self._select_server(
   1461             read_pref, session, address=address)
   1462         if not server.description.retryable_reads_supported:
   1463             retryable = False

File ...\\Lib\\site-packages\\pymongo\\mongo_client.py:1278, in MongoClient._select_server(self, server_selector, session, address)
   1275         raise AutoReconnect('server %s:%d no longer available'
   1276                             % address)
   1277 else:
-> 1278     server = topology.select_server(server_selector)
   1279     # Pin this session to the selected server if it's performing a
   1280     # sharded transaction.
   1281     if server.description.mongos and (session and
   1282                                       session.in_transaction):

File ...\\Lib\\site-packages\\pymongo\\topology.py:241, in Topology.select_server(self, selector, server_selection_timeout, address)
    236 def select_server(self,
    237                   selector,
    238                   server_selection_timeout=None,
    239                   address=None):
    240     \"\"\"Like select_servers, but choose a random server if several match.\"\"\"
--> 241     return random.choice(self.select_servers(selector,
    242                                              server_selection_timeout,
    243                                              address))

File ...\\Lib\\site-packages\\pymongo\\topology.py:199, in Topology.select_servers(self, selector, server_selection_timeout, address)
    196     server_timeout = server_selection_timeout
    198 with self._lock:
--> 199     server_descriptions = self._select_servers_loop(
    200         selector, server_timeout, address)
    202     return [self.get_server_by_address(sd.address)
    203             for sd in server_descriptions]

File ...\\Lib\\site-packages\\pymongo\\topology.py:215, in Topology._select_servers_loop(self, selector, timeout, address)
    212 while not server_descriptions:
    213     # No suitable servers.
    214     if timeout == 0 or now > end_time:
--> 215         raise ServerSelectionTimeoutError(
    216             \"%s, Timeout: %ss, Topology Description: %r\" %
    217             (self._error_message(selector), timeout, self.description))
    219     self._ensure_opened()
    220     self._request_check_all()

ServerSelectionTimeoutError: {service_name}.mongo.cosmos.azure.com:10255: timed out, Timeout: 30s, Topology Description: <TopologyDescription id: 6734b32d878003e1a30f46fb, topology_type: Single, servers: [<ServerDescription ('{service_name}.mongo.cosmos.azure.com', 10255) server_type: Unknown, rtt: None, error=NetworkTimeout('{service_name}.mongo.cosmos.azure.com:10255: timed out')>]>"
}

解决方案

针对Azure Cosmos DB MongoDB引擎的无服务器分片实例,调整连接参数和代码即可解决超时问题:

1. 修改连接字符串参数

无服务器实例不需要replicaSet=globaldb参数,且需要添加directConnection=true强制直连,调整后的连接字符串格式:

mongodb://{user_name}:{primary_key}@{service_name}.mongo.cosmos.azure.com:10255/?ssl=true&directConnection=true&retrywrites=false&maxIdleTimeMS=120000&appName=@{service_name}@

注意:如果主键包含特殊字符(如+、/、=),需进行URL编码,比如+替换为%2B,/替换为%2F,=替换为%3D

2. 匹配pymongo版本与MongoDB兼容版本

  • 若使用MongoDB 7.0兼容版本,需使用pymongo 4.6.0及以上版本
  • 若使用MongoDB 3.6兼容版本,可使用pymongo 3.6~4.0系列版本

3. 调整连接超时参数(可选)

在创建MongoClient时显式设置更长的超时时间,避免因无服务器实例冷启动导致的超时:

import pymongo

CONN_STRING = "调整后的连接字符串"

client = pymongo.MongoClient(
    CONN_STRING,
    serverSelectionTimeoutMS=60000,  # 设置为60秒
    connectTimeoutMS=30000
)

# 验证连接
try:
    client.admin.command('ping')
    print("连接成功")
    print("数据库列表:", client.list_database_names())
except Exception as e:
    print(f"连接失败: {e}")

4. 检查Cosmos DB实例配置

确认Azure Cosmos DB实例的网络访问控制设置为允许当前客户端IP,或者开启“允许从所有网络访问”(测试环境可临时开启验证)


内容的提问来源于stack exchange,提问作者ilVacca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 05:45:01