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--
相关产品推荐
相关产品推荐

