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

使用Google Sheets API v4及batchUpdate写入DataFrame遇序列化错误求助

解决Google Sheets API batchUpdate中的int64序列化错误

这个问题的核心是pandas的int64(numpy类型)不是Python原生整数类型,而JSON序列化只支持Python原生数据类型,导致API请求失败。另外你的batchUpdate请求体格式也有问题,得一起修正。

第一步:把pandas数据转换为Python原生类型

你可以写一个通用的转换函数,把numpy的数值类型转成原生类型,同时保留其他类型(比如字符串)不变:

import numpy as np
import pandas as pd

def convert_to_native(val):
    # 处理numpy整数类型
    if isinstance(val, np.integer):
        return int(val)
    # 处理numpy浮点数类型(如果你的DataFrame有float64也需要)
    elif isinstance(val, np.floating):
        return float(val)
    # 其他类型直接返回
    else:
        return val

然后用这个函数转换你的DataFrame:

# 转换DataFrame的所有元素为原生类型
df_native = orders_compact.applymap(convert_to_native)
# 生成包含表头和行数据的列表列表
values = [list(df_native.columns)] + df_native.values.tolist()

或者如果你不想写函数,也可以用更简洁的方式批量转换数值列:

# 把所有整数列转成Python原生int,浮点列转成原生float
for col in orders_compact.select_dtypes(include=['int64']).columns:
    orders_compact[col] = orders_compact[col].astype(int)
for col in orders_compact.select_dtypes(include=['float64']).columns:
    orders_compact[col] = orders_compact[col].astype(float)

# 生成values列表
values = [list(orders_compact.columns)] + orders_compact.values.tolist()

第二步:修正batchUpdate请求体格式

你原来的data字段格式不符合API要求,Google Sheets API的batchUpdate要求data是一个字典列表,每个字典需要包含range(要写入的单元格范围)和values(你的数据)。比如:

batch_update_values_request_body = {
    'value_input_option': 'USER_ENTERED',
    'data': [
        {
            # 指定要写入的范围,比如Sheet1的A1开始的区域,或者用动态范围
            'range': 'Sheet1!A1',
            'values': values
        }
    ]
}

如果想更精准地指定范围(比如匹配数据的行列数),可以这样生成range:

# 假设工作表名为Sheet1
sheet_name = 'Sheet1'
# 计算数据的列数(比如表头有N列,就到第N列)
num_cols = len(orders_compact.columns)
# 生成范围字符串,比如Sheet1!A1:X100(X对应列数,100对应行数)
range_str = f'{sheet_name}!A1:{chr(65 + num_cols - 1)}{len(values)}'

batch_update_values_request_body = {
    'value_input_option': 'USER_ENTERED',
    'data': [
        {
            'range': range_str,
            'values': values
        }
    ]
}

完整修正后的代码

把上面的步骤整合起来:

import numpy as np
import pandas as pd

# 1. 转换数据类型
def convert_to_native(val):
    if isinstance(val, np.integer):
        return int(val)
    elif isinstance(val, np.floating):
        return float(val)
    else:
        return val

df_native = orders_compact.applymap(convert_to_native)
values = [list(df_native.columns)] + df_native.values.tolist()

# 2. 构建正确的请求体
sheet_name = 'Sheet1'
num_cols = len(df_native.columns)
range_str = f'{sheet_name}!A1:{chr(65 + num_cols - 1)}{len(values)}'

batch_update_values_request_body = {
    'value_input_option': 'USER_ENTERED',
    'data': [
        {
            'range': range_str,
            'values': values
        }
    ]
}

# 3. 发送请求
request = service.spreadsheets().values().batchUpdate(spreadsheetId=SPREADSHEET_ID, body=batch_update_values_request_body)
response = request.execute()

为什么你之前的方法没生效?

  • 用astype的时候可能只处理了部分列,或者没有覆盖所有numpy数值类型(比如只转了int64但没转float64);
  • to_json方法是把DataFrame转成JSON字符串,而API需要的是可序列化的Python对象,不是字符串,所以这个方法不适用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 03:48:55