Pandas read_sql读取浮点字段值异常(小数位丢失数值放大)求助
解决Pandas read_sql读取数值时小数位丢失的问题
这问题我之前帮同事排查过,大概率是数值存储方式或者数据库驱动解析逻辑的锅,给你几个靠谱的解决方向:
1. 先确认数据库字段的实际存储逻辑
首先去数据库里查一下对应字段的类型:
- 如果字段是
INT/BIGINT类型(比如金额以分为单位存储),那SQL Developer里看到的小数是工具自动做了除以100的转换,而Pandas会直接读取原始整数。这种情况直接在Pandas里手动转换就行:
# 把目标字段除以100恢复成原数值 df['target_column'] = df['target_column'] / 100 # 如果需要保留两位小数,可以再加一步 df['target_column'] = df['target_column'].round(2)
- 如果字段是
NUMBER(precision, scale)(比如NUMBER(10,2))这类带小数位的数值类型,那问题出在驱动解析上,看下面的方案。
2. 强制指定字段数据类型读取
用pandas.read_sql的时候,通过dtype参数强制指定目标字段的类型,避免驱动自动解析出错:
import pandas as pd from sqlalchemy import create_engine # 替换成你的数据库连接字符串 engine = create_engine('your_db_connection_string') # 强制指定字段为float64或者Decimal类型 df = pd.read_sql( 'your_sql_query', engine, dtype={'target_column': 'float64'} )
如果需要更高精度的数值计算(比如金额场景),推荐用Decimal类型:
from decimal import Decimal # 先读取为整数,再转换为Decimal后除以100 df['target_column'] = df['target_column'].apply(lambda x: Decimal(x) / 100)
3. 检查数据库驱动的配置和版本
不同数据库的驱动可能有特殊参数需要设置:
- 比如使用
cx_Oracle连接Oracle数据库时,确保驱动版本是最新的,旧版本可能存在数值解析bug。可以升级驱动:
pip install --upgrade cx_Oracle
- 如果用
pyodbc连接SQL Server/其他数据库,尝试添加decimal_as_float=False参数到连接字符串,避免小数被转成整数:
conn_str = 'DRIVER={ODBC Driver 17 for SQL Server};SERVER=your_server;DATABASE=your_db;UID=user;PWD=password;decimal_as_float=False' df = pd.read_sql('your_sql_query', conn_str)
4. 验证查询语句的一致性
确保Pandas执行的SQL和你在SQL Developer里跑的完全一致,有没有不小心加了CAST(column AS INT)这类转换逻辑?先把SQL复制到Pandas里再执行,排除语句差异的问题。
最后可以先跑个简单的验证,看看读取后的字段类型:
print(df.dtypes)
如果显示是int64,那基本就是存储的是放大后的整数,直接除以100就行;如果是float64但数值不对,那就是驱动解析的问题,调整驱动参数或者类型指定就好。
内容的提问来源于stack exchange,提问作者João Pedro
相关产品推荐
相关产品推荐

