使用pyodbc查询SQL Server数据返回非预期格式,如何转换Decimal与日期时间值
解决方法
这类带类型包装的输出,是pyodbc的默认映射规则导致的:它会把SQL Server里高精度小数字段映射为Python原生Decimal类型,把日期类字段映射为Python原生date/datetime类型。只需要在遍历查询结果时对不同类型的值做统一格式化即可,不需要修改原SQL查询语句。
具体实现
- 补充导入需要的类型判断依赖:
from decimal import Decimal import datetime - 在遍历查询结果的循环里,逐字段判断类型并转换:
- 遇到
Decimal类型的值,按需转为浮点数或者不带包装的数值字符串 - 遇到
date/datetime类型的值,通过strftime方法转为常规可读的日期时间字符串
- 遇到
- 改造后的完整可运行代码:
import pyodbc from decimal import Decimal import datetime connection = pyodbc.connect( "Driver={SQL Server Native Client 11.0};" "Server=xxx;" "Database=xxx;" "uid=xxx;" "pwd=xxx;" ) cursor = connection.cursor() cursor.execute('SELECT * FROM Dealers') for row in cursor: formatted_result = [] for field_value in row: # 处理Decimal类型数值 if isinstance(field_value, Decimal): # 方案1:转为普通浮点数 formatted_result.append(float(field_value)) # 方案2:直接转成保留原小数位的字符串(比如输出83.360而不是83.36) # formatted_result.append(str(field_value)) # 处理日期时间类型 elif isinstance(field_value, datetime.datetime): # 按常用格式输出 年-月-日 时:分:秒 formatted_result.append(field_value.strftime("%Y-%m-%d %H:%M:%S")) elif isinstance(field_value, datetime.date): # 处理纯日期类型,无时分秒部分 formatted_result.append(field_value.strftime("%Y-%m-%d")) # 布尔、整数等其他类型直接保留原值即可 else: formatted_result.append(field_value) print(formatted_result)
效果说明
原来的输出内容
Decimal('0.000'), Decimal('83.360'), True, True, Decimal('0.000'), datetime.date(2017, 5, 31), True, 1, True, True, datetime.datetime(2017, 5, 31, 18, 28, 57, 686666),运行改造后的代码后会输出成类似[0.0, 83.36, True, True, 0.0, '2017-05-31', True, 1, True, True, '2017-05-31 18:28:57']的格式,没有多余的类型包装。
注意:如果业务场景对数值精度要求极高,不建议把Decimal转成浮点数,直接用str(field_value)转字符串即可完全保留原始的小数位数,不会出现浮点精度偏移问题。
内容的提问来源于stack exchange,提问作者Randy Minder
相关产品推荐
相关产品推荐

