尝试通过Python中的Google Sheets API将数据附加到Google表格

huangapple go评论53阅读模式
英文:

Trying to append data to google sheets via google sheets API in Python

问题

以下是代码部分的翻译:

from __future__ import print_function

import requests
import urllib.parse as urlparse
from googleapiclient import discovery
import os.path
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError


SCOPES = ['https://www.googleapis.com/auth/spreadsheets',
          'https://www.googleapis.com/auth/drive',
          'https://www.googleapis.com/auth/drive.file']

# The ID and range of a sample spreadsheet.
SAMPLE_SPREADSHEET_ID = '1_oKFw7gYmUWDUZxZ6Dgo1uLM9Tf_Bc-4bnq4jiJbQUs'
SAMPLE_RANGE_NAME = 'Sheet1'
creds = None

if not creds or not creds.valid:
    if creds and creds.expired and creds.refresh_token:
        creds.refresh(Request())
    else:
        flow = InstalledAppFlow.from_client_secrets_file(
            'credentials.json', SCOPES)
        creds = flow.run_local_server(port=0)
    # Save the credentials for the next run
    with open('token.json', 'w') as token:
        token.write(creds.to_json())
        
spreadsheet_id = '***************'
range_ = 'Sheet1!'
value_input_option = 'RAW'        

service = discovery.build('sheets', 'v4', credentials=creds)

value_range_body = ['a']

request = service.spreadsheets().values().append(spreadsheetId=spreadsheet_id, range=range_,                
valueInputOption=value_input_option, body=value_range_body)
response = request.execute()

以下是错误部分的翻译:

<HttpError 400 when requesting
https://sheets.googleapis.com/v4/spreadsheets/1_oKFw7gYmUWDUZxZ6Dgo1uLM9Tf_Bc-4bnq4jiJbQUs/values/Sheet1%21:append?valueInputOption=RAW&amp;alt=json returned "Invalid JSON payload received. Unknown name "": Root element
must be a message.". Details: "[{'@type':
'type.googleapis.com/google.rpc.BadRequest', 'fieldViolations':
[{'description': 'Invalid JSON payload received. Unknown name "": Root
element must be a message.'}]}]">

英文:

My intentions are to put the data extracted from places API into google sheets.
I have followed a lot of methods including using gspread library and making a service account and then authorizing it.

I am currently trying with the service account where I have passed on the credentials, built a service request, and then executed it. However, it is throwing me the following error Invalid JSON payload received. Unknown name

What am I doing wrong?

I wanted to append data in google sheets but I am getting an error.

Code

from __future__ import print_function

import requests
import urllib.parse as urlparse
from googleapiclient import discovery
import os.path
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError


SCOPES = [&#39;https://www.googleapis.com/auth/spreadsheets&#39;,
          &#39;https://www.googleapis.com/auth/drive&#39;,
          &#39;https://www.googleapis.com/auth/drive.file&#39;]

# The ID and range of a sample spreadsheet.
SAMPLE_SPREADSHEET_ID = &#39;1_oKFw7gYmUWDUZxZ6Dgo1uLM9Tf_Bc-4bnq4jiJbQUs&#39;
SAMPLE_RANGE_NAME = &#39;Sheet1&#39;
creds = None

if not creds or not creds.valid:
    if creds and creds.expired and creds.refresh_token:
        creds.refresh(Request())
    else:
        flow = InstalledAppFlow.from_client_secrets_file(
            &#39;credentials.json&#39;, SCOPES)
        creds = flow.run_local_server(port=0)
    # Save the credentials for the next run
    with open(&#39;token.json&#39;, &#39;w&#39;) as token:
        token.write(creds.to_json())
        
spreadsheet_id = &#39;***************&#39;
range_ = &#39;Sheet1!&#39;
value_input_option = &#39;RAW&#39;        



service = discovery.build(&#39;sheets&#39;, &#39;v4&#39;, credentials=creds)


value_range_body = [&#39;a&#39;]


request = service.spreadsheets().values().append(spreadsheetId=spreadsheet_id, range=range_,                
valueInputOption=value_input_option, body=value_range_body)
response = request.execute()

Error

> <HttpError 400 when requesting
> https://sheets.googleapis.com/v4/spreadsheets/1_oKFw7gYmUWDUZxZ6Dgo1uLM9Tf_Bc-4bnq4jiJbQUs/values/Sheet1%21:append?valueInputOption=RAW&amp;alt=json returned "Invalid JSON payload received. Unknown name "": Root element
> must be a message.". Details: "[{'@type':
> 'type.googleapis.com/google.rpc.BadRequest', 'fieldViolations':
> [{'description': 'Invalid JSON payload received. Unknown name "": Root
> element must be a message.'}]}]">

答案1

得分: 1

以下是翻译后的代码部分:

# 错误与如何解析`value_range_body`相关。如果您想要使用[spreadsheets.values.append](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append)方法,您可以基于以下示例编写代码:

*注意我使用的示例代码是基于数据库和OAuth的但请求正文应该是相同的*

from __future__ import print_function
import os.path
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

# 如果修改了这些范围,请删除token.json文件。
SCOPES = ['https://www.googleapis.com/auth/drive.file',
          'https://www.googleapis.com/auth/drive',
          'https://www.googleapis.com/auth/spreadsheets']

# 示例电子表格的ID和范围。
spreadsheetId = 'sheetID'

def main():
    creds = None

    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        with open('token.json', 'w') as token:
            token.write(creds.to_json())

    try:
        service = build('sheets', 'v4', credentials=creds)
        # 'records_df'是将插入表格中的数据变量。
        # 在您的情况下,它将是来自places API的数据
        records_db = [['2023-01-18', '1234', 'ABC', 1234],
                      ['2023-01-17', '5678', 'DEF', 5678],
                      ['2023-01-16', '9012', 'ABC', 9012]]

        # 'range_db'是要添加数据的范围。
        range_db = "Sheet1"
        value_input_option = "RAW"
        insert_data_option = "INSERT_ROWS"

        # 这是'value_range_body'或JSON
        value_range_body = {
            "majorDimension": "ROWS",
            "values": records_db,
        }

        request = service.spreadsheets().values().append(spreadsheetId=spreadsheetId,
                                                         range=range_db,
                                                         valueInputOption=value_input_option,
                                                         insertDataOption=insert_data_option,
                                                         body=value_range_body)
        response = request.execute()

    except HttpError as err:
        print(err)

if __name__ == '__main__':
    main()

希望这对您有所帮助!如果您有任何其他问题,请随时提问。

英文:

The error is related to how value_range_body is parse. If you want to use the method spreadsheets.values.append, you can base you code in the following sample:

Note: the sample code that I'm using is base on a database, and using OAuth, but the request body should be the same

from __future__ import print_function
import os.path
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
# If modifying these scopes, delete the file token.json.
SCOPES = [&#39;https://www.googleapis.com/auth/drive.file&#39;, 
&#39;https://www.googleapis.com/auth/drive&#39;,
&#39;https://www.googleapis.com/auth/spreadsheets&#39; ]
# The ID and range of a sample spreadsheet.
spreadsheetId = &#39;sheetID&#39;
def main():
creds = None
if os.path.exists(&#39;token.json&#39;):
creds = Credentials.from_authorized_user_file(&#39;token.json&#39;, SCOPES)
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
&#39;credentials.json&#39;, SCOPES)
creds = flow.run_local_server(port=0)
with open(&#39;token.json&#39;, &#39;w&#39;) as token:
token.write(creds.to_json())
try:
service = build(&#39;sheets&#39;, &#39;v4&#39;, credentials=creds)
# &#39;records_df&#39; is the variable with the data that will be inserted in the Sheet. 
# In your case it will be the data coming from places API
records_db = [[&#39;2023-01-18&#39;, &#39;1234&#39;, &#39;ABC&#39;, 1234], 
[&#39;2023-01-17&#39;, &#39;5678&#39;, &#39;DEF&#39;, 5678], 
[&#39;2023-01-16&#39;, &#39;9012&#39;, &#39;ABC&#39;, 9012]]
# &#39;range_db&#39; is the range of the where the data will be added.
range_db = &quot;Sheet1&quot;
value_input_option = &quot;RAW&quot;
insert_data_option = &quot;INSERT_ROWS&quot;
# This is the &#39;value_range_body&#39; or JSON
value_range_body = {
&quot;majorDimension&quot;: &quot;ROWS&quot;,
&quot;values&quot;: records_db,
}
request = service.spreadsheets().values().append(spreadsheetId=spreadsheetId, 
range=range_db, 
valueInputOption=value_input_option, 
insertDataOption=insert_data_option, 
body=value_range_body)
response = request.execute()
except HttpError as err:
print(err)
if __name__ == &#39;__main__&#39;:
main()

huangapple
  • 本文由 发表于 2023年2月18日 01:56:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75487745.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定