Reputation: 73
I try to append the google sheet with python df. After google sheet authorization, I tried this:
sheet = service.spreadsheets()
result = sheet.values().get(spreadsheetId=SAMPLE_SPREADSHEET_ID, range="Sheet1!A1:E100").execute()
values = result.get('values', [])
request = sheet.values().append(spreadsheetId=SAMPLE_SPREADSHEET_ID, range="Sheet1!A1", valueInputOption="USER_ENTERED", insertDataOption="INSERT_ROWS", body={"values":df}).execute()
but it gives me TypeError: Object of type DataFrame is not JSON serializable
So I tried this function, which allows to load and overwrite data into google sheet but not to append data:
def iter_pd(df):
for val in df.columns:
yield val
for row in df.to_numpy():
for val in row:
if pd.isna(val):
yield ""
else:
yield val
def pandas_to_sheets(pandas_df, sheet, clear = True):
# Updates all values in a workbook to match a pandas dataframe
if clear:
sheet.clear()
(row, col) = pandas_df.shape
cells = sheet.range("A1:{}".format(gspread.utils.rowcol_to_a1(row + 1, col)))
for cell, val in zip(cells, iter_pd(pandas_df)):
cell.value = val
sheet.update_cells(cells)
pandas_to_sheets(df, workbook.worksheet("Sheet1"))
I will be grateful for any suggestions.
Upvotes: 0
Views: 453
Reputation: 133
After some investigating I found a method using df.to_json()
that works for me:
to_json
returns a string thats json formatted and the sheets api expects a list instead.
So i used this call:
sheet.values().append(
spreadsheetId=SAMPLE_SPREADSHEET_ID,
range="Sheet1!A1",
valueInputOption="USER_ENTERED",
insertDataOption="INSERT_ROWS",
body={
"values": json.loads(df.to_json(orient='values'))
},
).execute()
with import json
beforehand.
orient='values'
formats the data as just a values array as required by the sheets api,
json.loads()
parses the generated json-string into a python object (list)
Upvotes: 2
Reputation: 1221
The body parameter in the request variable of your code should be in dict type and your dataframe should be converted to json.
Your code in your request variable should look like this(I replicated this on my end and it is working as expected):
request = sheet.values().append(spreadsheetId=SAMPLE_SPREADSHEET_ID, range="Sheet1!A1", valueInputOption="USER_ENTERED", insertDataOption="INSERT_ROWS", body={'values':df.to_json()}).execute()
Upvotes: 0