You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Pandas read_sql_query指定MySQL decimal(28,5)字段为Decimal类型的技术问询

如何在Pandas的read_sql_query中明确指定Decimal类型

问题根源

你遇到的TypeError是因为Pandas的dtype参数并不接受Python标准库的decimal.Decimal类作为合法输入——这个参数只识别Pandas/numpy兼容的 dtype 标识(比如字符串别名'Int64'、numpy dtype对象,或者Pandas扩展类型),直接传Decimal类它当然看不懂啦。

不过别担心,有两种方法可以帮你实现明确控制该字段为Decimal类型的需求:


方法1:用converters参数显式转换

read_sql_query自带的converters参数专门用来给指定列设置自定义转换逻辑,刚好可以用来强制把value列转成Decimal:

from decimal import Decimal
import pandas as pd

# 定义一个转换函数,确保输入值转为Decimal
def enforce_decimal(val):
    return Decimal(val)

# 其他列的dtype正常指定
dtypes = { 
    'id': 'Int64', 
    'date': 'datetime64' 
}

df = pd.read_sql_query(
    sql_query,
    mysql_engine,
    dtype=dtypes,
    coerce_float=False,
    converters={'value': enforce_decimal}  # 给value列绑定转换函数
)

这样一来,不管数据库驱动返回什么类型,value列都会被显式转换为decimal.Decimal,完全符合你的控制需求。


方法2:用Pandas Arrow Decimal dtype(适用于Pandas 2.0+)

如果你用的是Pandas 2.0及以上版本,可以直接用官方支持的Arrow Decimal dtype来指定,完美匹配MySQL的decimal(28,5)类型:

import pandas as pd

dtypes = { 
    'id': 'Int64', 
    'date': 'datetime64',
    'value': pd.ArrowDtype('decimal[28,5]')  # 对应数据库的decimal(28,5)
}

df = pd.read_sql_query(
    sql_query,
    mysql_engine,
    dtype=dtypes,
    coerce_float=False
)

注意这个方法需要你先安装pyarrow库(pip install pyarrow)。读取后的value列会是Arrow Decimal类型,和Python标准库的decimal.Decimal完全兼容,要是你需要转为标准Decimal对象,只需要用df['value'].apply(Decimal)就行。


补充:为什么不指定dtype时会自动返回Decimal?

当你不给value列指定dtype时,Pandas会直接沿用数据库驱动(比如mysql-connector-python)返回的类型——这些驱动会自动把MySQL的decimal字段转成Python的decimal.Decimal,Pandas则把它们存在object dtype的列里,所以你能看到单个元素的类型是Decimal。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 15:42:40