使用Python查询SQL数据并自动更新Google工作表

mgdq6dx1  于 2023-01-29  发布在  Python
关注(0)|答案(2)|浏览(169)

我正在尝试使用Python来查询我的SQL数据库,然后在Google工作表中更新结果。我已经完成了设置GC控制台所需的所有步骤,并且能够访问工作表。也成功连接到SQL数据库。

['2023-01-18', '5231', 'ABC', 6164368.0, 234712.0, 108554.0]
 ['2023-01-17', '5231', 'ABC', 6434784.0, 231475.0, 94775.0]
 ['2023-01-16', '5232', 'ABC', 6463684.0, 232513.0, 100168.0]

我想:

  • a)使用Python在我的Google工作表中更新相同的内容-Sheet1。
  • b)添加标题列,如DateIDNameOrderValuePurchaseValueClicks
  • c)工作表需要每天用新数据刷新,所以在插入值之前,我需要在python代码执行时清除工作表内容。

PFB代码片段

cursor.execute(SELECT_QUERY)
    result = cursor.fetchall()
    df_columns = [x[0] for x in cursor.description]
    i = 0
    data = {i: list(r[0:]) for i, r in enumerate(result)}
    for i in data:
        print(data[i])
pokxtpni

pokxtpni1#

为了给你一个想法,你可以尝试下面的代码,我添加了身份验证部分,以防你需要它。你可以调整它,以满足你的需要,但它基本上做了你上面问的。更多的细节,我在代码中添加了一些注解。如果你有任何问题,让我知道。

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
from pprint import pprint

# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/drive.file', 'https://www.googleapis.com/auth/drive','https://www.googleapis.com/auth/spreadsheets' ]

# The ID and range of a sample spreadsheet.
SAMPLE_SPREADSHEET_ID = 'SpreadsheetID'

def main():
    creds = None
    # The file token.json stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    # If there are no (valid) credentials available, let the user log in.
    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())

    try:
        service = build('sheets', 'v4', credentials=creds)
            
        # Call the Sheets API and the sheet ID
        #Clear content in Sheet1!A1:F
        call_sheet_with_format = service.spreadsheets().get(spreadsheetId=SAMPLE_SPREADSHEET_ID).execute()
        sheets_with_format = call_sheet_with_format.get('sheets', '')
        sheet_id = sheets_with_format[0].get("properties", {}).get("sheetId", 0)

        request_body = {
            'requests': [
                {
                    'updateCells': {
                        'range': {
                            'sheetId': sheet_id
                        },
                        'fields':'userEnteredFormat'
                    }
                }
            ]
        }

        request = service.spreadsheets().batchUpdate(spreadsheetId=SAMPLE_SPREADSHEET_ID, body=request_body).execute()
        request_clear = service.spreadsheets().values().clear(spreadsheetId=SAMPLE_SPREADSHEET_ID, range="Sheet1!A1:F").execute()

        # Call the Sheets API and the sheet ID
        #Adding headers to Sheet1
        call_sheet_with_format = service.spreadsheets().get(spreadsheetId=SAMPLE_SPREADSHEET_ID).execute()
        sheets_with_format = call_sheet_with_format.get('sheets', '')
        sheet_id = sheets_with_format[0].get("properties", {}).get("sheetId", 0)
        headers = "Date, ID, Name, OrderValue,PurchaseValue, Clicks"

        request_body = {
                        "requests": [
                        {
                            "insertRange": {
                                "range": {
                                            "sheetId": sheet_id,
                                            "startRowIndex": 0,
                                            "endRowIndex": 1
                                        },
                                "shiftDimension": "ROWS"
                            }
                        },
                        {
                        "pasteData": {
                            "data": headers,
                            "type": "PASTE_NORMAL",
                            "delimiter": ",",
                            "coordinate": {
                                            "sheetId": sheet_id,
                                            "rowIndex": 0,
                                        }
                                    }
                             }
                            ]
                        }

        request = service.spreadsheets().batchUpdate(spreadsheetId=SAMPLE_SPREADSHEET_ID, body=request_body)
        response = request.execute()
        pprint(response)
        
        #Adding the data that you retrieved from the database
        #For this to work, you need the data in the format below in 'records_df'
        records_df = [['2023-01-18', '5231', 'ABC', 6164368.0, 234712.0, 108554.0], ['2023-01-17', '5231', 'ABC', 6434784.0, 231475.0, 94775.0], ['2023-01-16', '5232', 'ABC', 6463684.0, 232513.0, 100168.0]]
        range_db = "Sheet1!A2:F"
        value_input_option = "USER_ENTERED"
        insert_data_option = "INSERT_ROWS"
        value_range_body = {
                        "majorDimension": "ROWS",
                        "values": records_df,
                        }
        
        request_2 = service.spreadsheets().values().append(spreadsheetId=SAMPLE_SPREADSHEET_ID, range=range_db, valueInputOption=value_input_option, insertDataOption=insert_data_option, body=value_range_body)
        response = request_2.execute()

    except HttpError as err:
        print(err)

if __name__ == '__main__':
    main()
x6h2sr28

x6h2sr282#

我用这种方法解决了它,有2个问题。如果我们更新行,它会用尽谷歌API的限制,所以我们必须更新列和转置它。这里我想更新列A-VPFB的代码片段。

def update_sheet(sheet, table, columns="ABCDEFGHIJKLMNOPQRSTUV", header=2):
    to_update = []
    table = list(zip(*table))  # transpose the table
    for col_name, col in zip(columns, table):  # iterating over columns now
        r = f"{col_name}{header}:{col_name}{len(col) + header}"  # changed range
        # print(r)  # for debugging
        cells = sheet.range(r)
        for cell, value in zip(cells, col):
            cell.value = value
        to_update.extend(cells)
    sheet.update_cells(to_update)

相关问题