Reputation: 113
Problem description: I want to create a program that can update one whole row (or cells in this row within given range) in one single line (i.e. one single API request).
This is what've seen in the documentation, that was related to my problem:
# Updates A2 and A3 with values 42 and 43
# Note that update range can be bigger than values array
worksheet.update('A2:B4', [[42], [43]])
This is how I tried to implement it into my program:
sheet.update(f'A{rowNumber + 1}:H{rowNumber + 1}', [[str(el)] for el in list_of_auctions[rowNumber]])
This is what printing [[str(el)] for el in list_of_auctions[rowNumber]]
looks like:
[['068222bb-c251-47ad-8c2a-e7ad7bad2f60'], ['urlLink'], ['100'], ['250'], ['20'], [''], [' ,'], ['0']]
As far as I can tell, everything here is according to the docs, however I get this output:
error from callback <bound method SocketHandler.handle_message of <amino.socket.SocketHandler object at 0x00000196F8C46070>>: {'code': 400, 'message': "Requested writing within range ['Sheet1'!A1:H1], but tried writing to row [2]", 'status': 'INVALID_ARGUMENT'}
File "C:\Users\1\Desktop\ИНФА\pycharm\venv\lib\site-packages\websocket\_app.py", line 344, in _callback
callback(*args)
File "C:\Users\1\Desktop\ИНФА\pycharm\venv\lib\site-packages\amino\socket.py", line 80, in handle_message
self.client.handle_socket_message(data)
File "C:\Users\1\Desktop\ИНФА\pycharm\venv\lib\site-packages\amino\client.py", line 345, in handle_socket_message
return self.callbacks.resolve(data)
File "C:\Users\1\Desktop\ИНФА\pycharm\venv\lib\site-packages\amino\socket.py", line 204, in resolve
return self.methods.get(data["t"], self.default)(data)
File "C:\Users\1\Desktop\ИНФА\pycharm\venv\lib\site-packages\amino\socket.py", line 192, in _resolve_chat_message
return self.chat_methods.get(key, self.default)(data)
File "C:\Users\1\Desktop\ИНФА\pycharm\venv\lib\site-packages\amino\socket.py", line 221, in on_text_message
def on_text_message(self, data): self.call(getframe(0).f_code.co_name, objects.Event(data["o"]).Event)
File "C:\Users\1\Desktop\ИНФА\pycharm\venv\lib\site-packages\amino\socket.py", line 209, in call
handler(data)
File "C:\Users\1\Desktop\python bots\auction-bot\bot.py", line 315, in on_text_message
bid_rub(link, data.message.author.nickname, data.message.author.userId, id, linkto)
File "C:\Users\1\Desktop\python bots\auction-bot\bot.py", line 162, in bid_rub
sheet.update(f'A{ifExisting + 1}:H{ifExisting + 1}', [[str(el)] for el in list_of_auctions[ifExisting]])
File "C:\Users\1\Desktop\ИНФА\pycharm\venv\lib\site-packages\gspread\utils.py", line 592, in wrapper
return f(*args, **kwargs)
File "C:\Users\1\Desktop\ИНФА\pycharm\venv\lib\site-packages\gspread\models.py", line 1096, in update
response = self.spreadsheet.values_update(
File "C:\Users\1\Desktop\ИНФА\pycharm\venv\lib\site-packages\gspread\models.py", line 235, in values_update
r = self.client.request('put', url, params=params, json=body)
File "C:\Users\1\Desktop\ИНФА\pycharm\venv\lib\site-packages\gspread\client.py", line 73, in request
raise APIError(response)
Question: I cannot figure out what can be the issue here, trying to tackle this for quite a while.
Upvotes: 1
Views: 3636
Reputation: 5533
The error indicates that the data you are trying to write has more rows than the rows in the range. Each list inside your list represent single row of data in the spreadsheet.
In your example:
[['068222bb-c251-47ad-8c2a-e7ad7bad2f60'], ['urlLink'], ['100'], ['250'], ['20'], [''], [' ,'], ['0']]
It represents 8 rows of data.
row 1 = ['068222bb-c251-47ad-8c2a-e7ad7bad2f60']
row 2 = ['urlLink']
row 3 = ['100']
row 4 = ['250']
row 5 = ['20']
row 6 = ['']
row 7 = [' ,']
row 8 = ['0']
If you want to write into a single row, the format should be:
[['068222bb-c251-47ad-8c2a-e7ad7bad2f60', 'urlLink', '100', '250', '20', '', ' ,', '0']]
To solve this, remove the [
and ]
in [str(el)]
and add another [
and ]
to str(el) for el in list_of_auctions[rowNumber]
or use itertools.chain() to make single list within a list
Your code should look like this:
sheet.update(f'A{rowNumber + 1}:H{rowNumber + 1}', [[str(el) for el in list_of_auctions[rowNumber]]])
or
import itertools
sheet.update(f'A{rowNumber + 1}:H{rowNumber + 1}', [list(itertools.chain(str(el) for el in list_of_auctions[rowNumber]))]
Upvotes: 1
Reputation: 196
Hi you may try the following:
def gs_writer(sheet_name,dataframe,sheet_url,boolean,row,col):
import gspread
from gspread_dataframe import get_as_dataframe, set_with_dataframe
import google.oauth2
from oauth2client.service_account import ServiceAccountCredentials
scope = ['https://spreadsheets.google.com/feeds','https://www.googleapis.com/auth/drive']
credentials = ServiceAccountCredentials.from_json_keyfile_name('gsheet_credentials.json', scope)
gc = gspread.authorize(credentials)
sht2 = gc.open_by_url(sheet_url)
sht = sht2.worksheet(sheet_name)
set_with_dataframe(sht,dataframe,resize = boolean,row=row,col=col)
Now after defining this function, you may simply get your required data in a dataframe and input your row and col number where you want this printed, like this:
gs_writer("sheet_name",df,sheet_url,False,1,1)
This should write your data starting from A1
Upvotes: 0