You need to enable JavaScript to run this app. PyMongo读写MongoDB数值字段为何返回Python float而非BSON Decimal128/Double?
优惠活动
大模型
产品
解决方案
定价
更多

PyMongo读写MongoDB数值字段为何返回Python float而非BSON Decimal128/Double?

核心原因说明

本质是PyMongo的默认反序列化映射规则,不存在类型读取错误,也不是type()方法使用不当。

  • BSON协议层定义的64位双精度浮点类型(BSON Double),和Python原生float的实现(遵循IEEE 754双精度规范)完全等价。PyMongo出于易用性考虑,默认将该类BSON值直接反序列化为Python原生float,不会额外封装为单独的bson.double类——所谓的bson.double只是协议层的类型标识,并非PyMongo对外暴露的Python类。类似的映射规则也适用于其他和Python原生行为对齐的BSON类型,比如BSON字符串对应Python原生str、BSON整数在精度匹配时对应Python原生int,只有原生Python类型无法完整表达BSON语义的场景,PyMongo才会提供专门的包装类。
  • 你当前插入操作传入的是Python原生float值,MongoDB会将其直接存储为BSON Double类型,读取时按照默认规则映射为Python原生float,因此type()输出<class 'float'>是完全符合设计逻辑的。
  • 你预期看到的bson.decimal128.Decimal128类型,对应BSON协议层的128位高精度十进制浮点类型。只有当你主动传入Decimal128类的实例作为插入值时,MongoDB才会将该字段存储为BSON Decimal128类型,读取时才会返回对应的Decimal128对象。普通float、decimal.Decimal类型的值不会被PyMongo自动转换为Decimal128存储。
验证示例

如果需要让读取结果返回Decimal128类型对象,需要显式构造该类型的实例插入:

from pymongo import MongoClient
from bson import Decimal128

db = MongoClient("mongodb://localhost/")["admin"]
collection = db["collection_test"]
collection.insert_one({
    "key1": Decimal128("1000000000.1"),
    "key2": Decimal128("1.1")
})
doc = collection.find_one()
print(type(doc["key1"])) # 输出<class 'bson.decimal128.Decimal128'>
print(type(doc["key2"])) # 输出<class 'bson.decimal128.Decimal128'>
补充说明

如果需要查询获取字段对应的原始BSON类型标识,不能直接靠读取文档值的type()判断,需要配合MongoDB的$type查询操作符,或者直接调用PyMongo的底层BSON解析接口获取原始类型元数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 09:06:07