Как обновить строку в одной строке с помощью API Google Таблиц?

Описание проблемы: я хочу создать программу, которая может обновлять одну целую строку (или ячейки в этой строке в заданном диапазоне) в одной строке (т. е. один запрос 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)

Вопрос: Я не могу понять, в чем может быть проблема, пытаюсь решить эту проблему довольно долго.

Основываясь на вашей трассировке {'code': 400, 'message': "Requested writing within range ['Sheet1'!A1:H1], but tried writing to row [2]", 'status': 'INVALID_ARGUMENT'}, обратитесь к этому.

Erick Y. Carreno 21.12.2020 20:05

Нет информации о том, почему это должно происходить и как этого избежать, поэтому документы не поддерживаются.

JoshJohnson 21.12.2020 20:13
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
2 575
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Привет, вы можете попробовать следующее:

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 21.12.2020 20:12

@JoshJohnson: нет, он начнет обновлять ваш фрейм данных с указанного вами номера строки и столбца. так, например, в вашем df, если у вас есть 1 строка с 5 столбцами, она обновит A1: E1, а если наоборот, она обновит A1: A5.

Prateek Jain 21.12.2020 20:17

@JoshJohnson: с какой проблемой вы столкнулись? Я использую его каждый день на работе, и, кажется, он работает отлично.

Prateek Jain 21.12.2020 21:24

Я просто получаю неразрешенную ошибку ссылки при ссылке на gspread_dataframe

JoshJohnson 21.12.2020 21:25

очень простое уточнение, но вы установили gspread_dataframe как отдельную библиотеку? Поскольку он не является частью официального модуля gspread, его необходимо установить самостоятельно.

Prateek Jain 21.12.2020 21:27
Ответ принят как подходящий

Ошибка указывает на то, что данные, которые вы пытаетесь записать, содержат больше строк, чем строк в диапазоне. Каждый список внутри вашего списка представляет одну строку данных в электронной таблице.

В вашем примере:

[['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]))]

Ссылка:

Запись в один диапазон

Itertools Python

Другие вопросы по теме