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

Python导入SQL Server数据至Google Sheets报错:Row无法JSON序列化

解决pyodbc Row对象无法序列化到Google Sheets的问题

问题根源

从SQL Server导出数据到Google Sheets时触发TypeError: Object of type Row is not JSON serializable,原因有两点:

  • pyodbc的cursor.fetchall()返回的是Row对象列表,而非Google Sheets API可识别的普通Python数据结构
  • Row对象中包含Decimal、datetime这类无法直接JSON序列化的特殊类型

解决方案

1. 转换Row对象为可序列化的普通列表

遍历查询结果,将每个Row转为普通列表,同时处理特殊类型:

  • Decimal:转为float(或字符串保留精度)
  • datetime:转为ISO格式字符串,方便Google Sheets自动识别为日期

2. 批量写入优化性能

80万条数据循环写入效率极低,建议用批量更新方法替代逐行写入,避免触发API配额限制。

修改后的完整代码

import pyodbc
import gspread
from google.oauth2 import service_account
from decimal import Decimal
import datetime

# 数据库连接配置
server = 'xxx.xxx.xxx.xxx, 1433'
database = 'DATADB'
username = 'XXX_XX'
password = 'PASSWORDXXX'
cnxn = pyodbc.connect(
    'DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+
    ';DATABASE='+database+';UID='+username+';PWD='+ password
)
cursor = cnxn.cursor()

# 执行查询并获取结果
cursor.execute("SELECT * FROM dbo.cosillastabla")
rows = cursor.fetchall()

# 处理数据:转换Row对象+特殊类型序列化
processed_rows = []
for row in rows:
    converted_row = []
    for item in row:
        if isinstance(item, Decimal):
            # 如需保留精确值,替换为 str(item)
            converted_row.append(float(item))
        elif isinstance(item, datetime.datetime):
            # 转为ISO格式,Google Sheets自动识别为日期
            converted_row.append(item.isoformat())
        else:
            converted_row.append(item)
    processed_rows.append(converted_row)

# Google Sheets授权
SERVICE_ACCOUNT_FILE = 'keys.json'
SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
SAMPLE_SPREADSHEET_ID = 'kjsdfkjfjksdjkfsdfsdhfsdkjfhsjf'
credentials = service_account.Credentials.from_service_account_file(
    SERVICE_ACCOUNT_FILE, scopes=SCOPES
)

# 使用gspread批量写入(简洁易维护)
gc = gspread.authorize(credentials)
sheet = gc.open_by_key(SAMPLE_SPREADSHEET_ID).worksheet('temilla')
# 从B2单元格开始写入二维列表数据
sheet.update('B2', processed_rows, value_input_option='USER_ENTERED')

# (可选)使用Sheets API批量写入(适合精细控制场景)
# service = build('sheets', 'v4', credentials=credentials)
# sheet_service = service.spreadsheets()
# request = sheet_service.values().update(
#     spreadsheetId=SAMPLE_SPREADSHEET_ID,
#     range='temilla!B2',
#     valueInputOption='USER_ENTERED',
#     body={'values': processed_rows}
# ).execute()

# 关闭数据库连接
cursor.close()
cnxn.close()

注意事项

  • 80万条数据属于大体积数据,建议分批次写入(比如每10000条一批),避免触发Google API的配额限制
  • 若需保留Decimal的精确数值,将float(item)替换为str(item),后续可在Google Sheets中手动转换为数字格式
  • 原代码中混用了Sheets API响应对象和gspread方法(request.append_row),这是错误用法,需统一使用一种操作方式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 21:45:46