【问题标题】:python (gspread) - whole data table placed in one cell of my Google Sheets instead of separate cellspython (gspread) - 整个数据表放在我的 Google 表格的一个单元格中,而不是单独的单元格中
【发布时间】:2020-08-07 21:01:40
【问题描述】:

我的目标是通过将第一个工作表的内容替换为我自己的数据表(即针对类属性的实例表)来更新 Google 表格文档。我曾尝试使用模块 gspread 来执行此操作,但效果不佳:如果我运行该行

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

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

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

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

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

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

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

非常感谢任何帮助。

【问题讨论】:

    标签: python json pandas google-sheets gspread


    【解决方案1】:

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

    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。非常强大,但需要更多样板代码。如果您比较两个代码示例,您可以看到这一点。这是一个权衡。

    【讨论】:

    • 好的,太好了!这正是我一直在寻找的。 Sheets API 在哪些方面更强大?
    • Sheets API 涵盖了庞大的功能集,几乎用户可以通过 Google 表格 UI 执行的所有操作,甚至更多。例如,查看大量的 batchUpdate Requests reference。相反,gspread 的目标是提供一些快捷方式来快速完成任务。因此,如果您正在构建一个严重依赖 Google Sheets API 的复杂应用程序,我会选择官方客户端。对于一个快速的解决方案,试验或绘制 gspread 可能会为您节省一些打字时间:)
    【解决方案2】:

    正如官方 Sheets API 在Method: spreadsheets.values.append Request body 所说的那样

    请求正文包含 ValueRange 的一个实例。

    ValueRange 是一个 JSON,它必须包含一个名为 values 的键,该键必须是一个数组数组。我根据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 列表。

    【讨论】:

    • 谢谢!!所以我根本不应该使用 gspread 。上面的代码非常适合我的数据。但是,in 仅包括数据本身,不包括列标题或行索引。我怎么能包括这些呢?只能分开做吗?
    • 使用官方的Google Sheets API比使用非官方的Gspread好。检查this question(有7个赞成票的那个),它会给你一个关于如何获取标题的想法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-04
    • 2021-12-07
    • 1970-01-01
    • 1970-01-01
    • 2010-11-12
    • 1970-01-01
    相关资源
    最近更新 更多