python (gspread) - 整个数据 table 放在我的 Google 工作表的一个单元格中,而不是单独的单元格

python (gspread) - whole data table placed in one cell of my Google Sheets instead of separate cells

我的目标是更新 Google Sheets 文档,方法是用我自己的数据 table 替换第一个 sheet 的内容(即 table 的实例对 class 的属性)。我曾尝试使用模块 gspread 来执行此操作,但效果并不理想:如果我 运行 行

client.open("GoogleSheetName").sheet1.update('A1:R181',Member.display().to_json())

(其中 Member 是我的 class,而 display() 是我自己的 class 方法,它只是将我的数据转换为 pandas dataFrame 对象。),整个 Member.display().to_json() 字符串被放入单元格 A1 中,就好像它从未被解包并且只是作为一个字符串保留一样。 如果我使用 json 模块并使用 json.dumps(Member.display().to_dict()) 转储我的数据,我会遇到同样的问题。

我还尝试简单地将数据更改为 Member.display().to_dict(),在这种情况下,我收到“Invalid JSON payload received”错误。

似乎数据可能需要采用矩阵格式才能工作,即 [[..,..,..][..,..,..]...],因为这是我的情况下唯一可以正常工作的格式。我知道它有效,因为当我通过 运行ning

测试 API 时
client.open("GoogleSheetName").sheet1.update('A1:B2', [[1, 2], [3, 4]])

每个数字都根据需要放在自己单独的单元格中。那是我必须使用的格式吗?

我该如何解决这个问题?就像我的数据需要发送 JSON 可读但不能是字符串,否则它会被解释为单个参数!

非常感谢任何帮助。

正如官方表格 API 在 Method: spreadsheets.values.append Request body

中所说

The request body contains an instance of ValueRange.

ValueRange is a JSON that must contain a key named values that must be an array of arrays. I made the following example based on the Python Quickstart 向您展示如何将您想要的数据传递到您的电子表格。

  service = discovery.build('sheets', 'v4', credentials=creds)
    spreadsheet_id = 'YOUR-SHEETS-ID'
    ranges = "A1:A"
    value_render_option = "DIMENSION_UNSPECIFIED"
    value_input_option = "USER_ENTERED"

    df = pd.DataFrame({
        'age':    [ 3,  29],
        'height': [94, 170],
        'weight': [31, 115]
    })

    value_range_body = {
        "values": df.to_numpy().tolist(),
        "majorDimension": "DIMENSION_UNSPECIFIED"
    }

    request = service.spreadsheets().values()\
        .append(spreadsheetId=spreadsheet_id, range=ranges, valueInputOption=value_input_option, body=value_range_body)

    response = request.execute()
    print(response)

如您所见,我正在使用 df.to_numpy().tolist() 将 pandas 数据帧转换为 NumPy 数组,然后转换为普通的 Python 列表。

如果 Member.display() 是一个 pandas DataFrame,您可以使用 gspread 执行以下操作来更新 sheet:

df = Member.display()
ws = client.open("GoogleSheetName").sheet1
ws.update([df.columns.values.tolist()] + df.values.tolist())

有关使用 gspread with pandas 的其他示例在文档中。

旁注:

当然,您可以使用 Alberto 指出的官方 API。这完全取决于您的用例。 Google Sheets API 是较低级别的 API。非常强大,但需要更多样板代码。如果比较这两个代码示例,您就会看到这一点。这是一个权衡。