如何用pandas read_sql_query将MySQL double字段读取为Decimal并保留全位数
你现在遇到的尾部0丢失、无法直接指定decimal类型的问题,原因有两个:一是pandas的dtype参数原生不支持直接映射到Python标准库的Decimal类型;二是Float64属于浮点数类型,本身不会存储尾部无意义的0,读取时会自动截断,还存在精度丢失的风险。
方案1:字符串中转(兼容性最好)
读取时先将目标字段指定为字符串类型,完全保留原始数值的字符格式,再手动转为Decimal类型,操作如下:
import pandas as pd from decimal import Decimal # 读取时指定value列为字符串类型,避免精度损失和尾部0截断 dtypes = { 'id': 'Int64', 'date': 'datetime64', 'value': str } df = pd.read_sql_query(sql_query, mysql_engine, dtype=dtypes) # 转为Decimal类型,pandas 1.3+支持指定DecimalDtype固定保留8位小数 # 低版本pandas可以省略astype步骤,列将以object类型存储Decimal对象 df['value'] = df['value'].apply(Decimal).astype(pd.DecimalDtype(scale=8))
方案2:SQL层面强制转换
在查询语句中直接将字段转为DECIMAL类型,利用SQLAlchemy的类型映射直接返回Decimal对象:
# 查询时直接对目标字段做类型转换,替换你自己的表名和查询条件 sql_query = "SELECT id, date, CAST(value AS DECIMAL(24,8)) AS value FROM 你的表名" df = pd.read_sql_query(sql_query, mysql_engine) # 可选:转为pandas原生Decimal类型固定小数位 df['value'] = df['value'].astype(pd.DecimalDtype(scale=8))
两种方案都可以完整保留8位小数,同时避免浮点数的精度误差问题。
内容的提问来源于stack exchange,提问作者wawawa
相关产品推荐
相关产品推荐

