【解决方法】Pymongo insert 卡住

本文介绍了一个使用 Pymongo 执行 insert 操作时出现的程序卡顿问题及其解决办法。问题表现为 insert 操作既不返回结果也不抛出异常,通过设置 MongoDB 连接的超时时间解决了该问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

先说一下标题,当我不知道问题的具体原因的时候,上面的标题就是我在搜索引擎中输入的内容。同样的,我还尝试过以下几种搜索组合:

Pymongo insert hangs
Pymongo insert stop
Pymongo insert no return
MongoDB insert hangs
MongoDB insert stop
MongoDB insert no return

从上面几个搜索的关键词,大家也能看出来问题的基本背景,就是使用 Pymongo 执行 insert,但是卡住了。

所说的卡住了,就是说,没有返回值,没有异常,没有报错,就是程序走到那里就不继续向下执行了。

问题描述

以下是代码的基本结构:

	clt = MongoClient("mongodb://192.168.x.x:27017")
    db = clt['test_bottle']
    col = dest_db['test_result']
    
    idx = 0
    rs = []
    for r in records:
        rs.append(r)
        idx += 1

        if idx % 100 == 0:
            col.insert_many(rs)
            rs = []

可以看到,很简单,很基础的代码,就是循环插入。问题的现象就是,代码执行到 col.insert_many(rs) 的时候,偶尔会出现程序卡住的情况。

这个卡住是随机的,有时候执行几次就卡住,有时候数据跑完一圈(几百万条数据)也没卡住。

奇怪吧。

这个问题比较诡异的就是,为什么会卡住,如果有问题,你报错就可以了,我捕获异常,然后特殊处理就可以,但是为什么会卡住。

问题分析

行了,直接说问题原因吧:

没有设置超时时间。

可能有的人会很奇怪,这个东西跟超时时间有什么关系?

我们来看一下 MongoDB 的官方文档

在这里插入图片描述

可以看到,关于超时时间的设定一共有两个,分别是 connectTimeoutMSsocketTimeoutMS,有点类似之前说过的 requests 模块的 connect timeoutread timeout,即:连接超时时间读取超时时间

这里比较坑的问题就出现了,这两个配置的默认值是 不超时(never to timeout)

所以,当我们没有执行这两个配置的时候,程序就会一直等待连接或者等待读取数据,也就是咱们上面所说的「卡住」。

解决方法

既然知道了问题原因,那解决思路就清晰了,设置一下超时时间即可。

设置的方式也有很多种,比如我这里就是直接修改了 MongoDB 的连接 uri:

也就是把上面的

clt = MongoClient("mongodb://192.168.x.x:27017")

修改为

clt = MongoClient("mongodb://192.168.x.x:27017/?socketTimeoutMS=3000&connectTimeoutMS=3000")

我这里设置的超时时间都是 3000(3s),大家可以根据自身情况自行设置。

当然,如果这样设置完了之后,记得捕获异常,然后做特殊处理。

好了,今天就和大家分享到这里,祝大家变得更强。

补充知识点:

卡住的「卡」音 qiǎ,不是

<think>我们正在讨论如何使用pymongoinsert_one方法插入数据。根据引用[1]和[2],insert_one的基本用法是创建一个字典(表示要插入的文档),然后调用insert_one方法。步骤:1.连接到MongoDB数据库。2.选择数据库和集合。3.创建一个字典(文档)作为要插入的数据。4.调用集合的insert_one方法,传入该字典。示例代码:```pythonimportpymongo#创建MongoDB连接,默认连接到本地27017端口myclient=pymongo.MongoClient("mongodb://localhost:27017/")#选择数据库(如果不存在,会在第一次插入数据时创建)mydb=myclient["mydatabase"]#选择集合(类似于表),如果不存在则创建mycol=mydb["customers"]#创建要插入的文档(字典形式)mydict={"name":"Bill","address":"Highway37"}#插入文档x=mycol.insert_one(mydict)#输出插入文档的_idprint(x.inserted_id)```注意点:-每个插入的文档都会自动生成一个唯一的`_id`(如果文档中没有指定_id字段)。如果需要指定_id,可以在字典中加入`_id`键,例如:`mydict={"_id":1,"name":"Bill","address":"Highway37"}`。-insert_one()方法返回InsertOneResult对象,该对象包含inserted_id属性(即插入文档的_id值)。引用[3]中还展示了如何根据_id判断是插入新文档还是更新已有文档(但用户问题只关注插入)。引用[4]提到pymongo的增删改查,但未给出具体内容。因此,我们专注于insert_one的基本用法。相关问题:1.如何插入多个文档?(使用insert_many)2.插入文档时如何自定义_id?3.插入文档后如何获取插入的_id?4.插入文档时遇到重复键错误(例如自定义_id重复)如何处理?</think>### 如何使用 PyMongo 的 `insert_one()` 方法插入数据 `insert_one()` 是 PyMongoMongoDB 插入单条文档的核心方法。以下是详细用法和示例: #### 基础步骤 1. **建立数据库连接** ```python from pymongo import MongoClient # 连接本地 MongoDB 实例 client = MongoClient("mongodb://localhost:27017/") # 选择数据库(不存在则自动创建) db = client["mydatabase"] # 选择集合(类似 SQL 表) collection = db["customers"] ``` 2. **创建文档(字典格式)** ```python document = { "name": "Alice", "email": "alice@example.com", "age": 30, "address": { "street": "Main St 123", "city": "New York" } } ``` 3. **执行插入操作** ```python result = collection.insert_one(document) print("插入文档的ID:", result.inserted_id) # 输出类似 ObjectId('5f3b...') ``` #### 关键特性说明 1. **自动生成 _id** 如果文档不包含 `_id` 字段,MongoDB 会自动生成唯一 ObjectId[^1][^2]: ```python # 不指定 _id doc = {"product": "Laptop", "price": 1200} result = collection.insert_one(doc) print(result.inserted_id) # 输出新生成的 ObjectId ``` 2. **自定义 _id** 可主动指定 _id 值(需确保唯一性): ```python doc = { "_id": "cust_001", # 自定义ID "name": "Bob", "membership": "premium" } collection.insert_one(doc) ``` 3. **插入结果处理** `insert_one()` 返回 `InsertOneResult` 对象: ```python result = collection.insert_one({"data": "test"}) # 获取插入状态 print("是否成功:", result.acknowledged) # True/False print("文档ID:", result.inserted_id) ``` #### 完整示例 ```python from pymongo import MongoClient # 1. 连接数据库 client = MongoClient("mongodb://localhost:27017/") db = client["shop_db"] products = db["products"] # 2. 准备文档 new_product = { "name": "Wireless Mouse", "brand": "Logitech", "price": 29.99, "stock": 50, "tags": ["electronics", "accessories"] } # 3. 插入数据 try: result = products.insert_one(new_product) print(f"插入成功! 文档ID: {result.inserted_id}") except Exception as e: print("插入失败:", str(e)) # 4. 验证插入 print("最新插入的文档:") print(products.find_one({"_id": result.inserted_id})) ``` #### 应用场景 - 用户注册信息存储 - 实时传感器数据记录 - 日志事件写入 - 表单提交数据保存 #### 注意事项 1. **原子性操作** 每次 `insert_one()` 是原子操作,要么完全成功,要么完全失败[^4]。 2. **网络错误处理** 建议使用 try-except 捕获网络异常: ```python try: collection.insert_one({"critical_data": 123}) except pymongo.errors.ConnectionFailure: print("数据库连接失败!") ``` 3. **写入确认** 默认不等待服务器确认,需高性能时可配置: ```python # 强制等待写入完成 collection.insert_one(data, w=1) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值