Описание проблемы: я хочу создать программу, которая может обновлять одну целую строку (или ячейки в этой строке в заданном диапазоне) в одной строке (т. е. один запрос API).
Это то, что я видел в документации, связанной с моей проблемой:
# 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]])
Вот как я пытался реализовать это в своей программе:
sheet.update(f'A{rowNumber + 1}:H{rowNumber + 1}', [[str(el)] for el in list_of_auctions[rowNumber]])
Вот так выглядит печать [[str(el)] for el in list_of_auctions[rowNumber]]
:
[['068222bb-c251-47ad-8c2a-e7ad7bad2f60'], ['urlLink'], ['100'], ['250'], ['20'], [''], [' ,'], ['0']]
Насколько я могу судить, здесь все соответствует документам, однако я получаю такой вывод:
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)
Вопрос: Я не могу понять, в чем может быть проблема, пытаюсь решить эту проблему довольно долго.
Нет информации о том, почему это должно происходить и как этого избежать, поэтому документы не поддерживаются.
Привет, вы можете попробовать следующее:
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)
Теперь, после определения этой функции, вы можете просто получить необходимые данные в фрейме данных и ввести номер строки и столбца, где вы хотите, чтобы это было напечатано, например:
gs_writer("sheet_name",df,sheet_url,False,1,1)
Это должно записывать ваши данные, начиная с A1
Вызов этой функции один раз может помочь мне отредактировать только одну конкретную ячейку, верно?
@JoshJohnson: нет, он начнет обновлять ваш фрейм данных с указанного вами номера строки и столбца. так, например, в вашем df, если у вас есть 1 строка с 5 столбцами, она обновит A1: E1, а если наоборот, она обновит A1: A5.
@JoshJohnson: с какой проблемой вы столкнулись? Я использую его каждый день на работе, и, кажется, он работает отлично.
Я просто получаю неразрешенную ошибку ссылки при ссылке на gspread_dataframe
очень простое уточнение, но вы установили gspread_dataframe как отдельную библиотеку? Поскольку он не является частью официального модуля gspread, его необходимо установить самостоятельно.
Ошибка указывает на то, что данные, которые вы пытаетесь записать, содержат больше строк, чем строк в диапазоне. Каждый список внутри вашего списка представляет одну строку данных в электронной таблице.
В вашем примере:
[['068222bb-c251-47ad-8c2a-e7ad7bad2f60'], ['urlLink'], ['100'], ['250'], ['20'], [''], [' ,'], ['0']]
Он представляет 8 строк данных.
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']
Если вы хотите записать в одну строку, формат должен быть:
[['068222bb-c251-47ad-8c2a-e7ad7bad2f60', 'urlLink', '100', '250', '20', '', ' ,', '0']]
Чтобы решить эту проблему, удалите [
и ]
в [str(el)]
и добавьте еще [
и ]
в str(el) for el in list_of_auctions[rowNumber]
или используйте itertools.chain(), чтобы создать один список в списке.
Ваш код должен выглядеть так:
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]))]
Основываясь на вашей трассировке
{'code': 400, 'message': "Requested writing within range ['Sheet1'!A1:H1], but tried writing to row [2]", 'status': 'INVALID_ARGUMENT'}
, обратитесь к этому.