如何使用Python/pyodbc将数据推送到Google工作表?

如何使用Python/pyodbc将数据推送到Google工作表?,python,google-sheets,google-sheets-api,google-api-python-client,Python,Google Sheets,Google Sheets Api,Google Api Python Client,开场白:我对Python非常陌生。:) 我已经获取了谷歌的信息,并且可以使用读/写权限成功连接到我的谷歌工作表,并清除工作表中以前的任何信息。此外,我能够遵循,并且能够成功地连接到我们使用的MSSQL服务器,并写出MSSQL表的Excel副本 但是,我似乎不知道如何将表MSSQL查询结果附加到Google工作表中。在VSCode中,它确实提供了回溯中的最新调用,并且似乎工作正常,没有错误。但是,该工作表不会得到更新 注意:如果我将dfListFormat的值更改为文本字符串,它会将该值附加到目标

开场白:我对Python非常陌生。:)

我已经获取了谷歌的信息,并且可以使用读/写权限成功连接到我的谷歌工作表,并清除工作表中以前的任何信息。此外,我能够遵循,并且能够成功地连接到我们使用的MSSQL服务器,并写出MSSQL表的Excel副本

但是,我似乎不知道如何将表MSSQL查询结果附加到Google工作表中。在VSCode中,它确实提供了回溯中的最新调用,并且似乎工作正常,没有错误。但是,该工作表不会得到更新

注意:如果我将
dfListFormat
的值更改为文本字符串,它会将该值附加到目标范围的A1中

value_range_body = {
        "majorDimension": "ROWS",
        "values": [
            [dfListFormat]
        ]
    }  
下面是我目前拥有的完整代码。如果您能提供任何帮助/建议,我们将不胜感激

from __future__ import print_function
import httplib2
import oauth2client
import os
import googleapiclient
import openpyxl
import pandas
import pyodbc

from apiclient import discovery
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage
from googleapiclient.discovery import build
from openpyxl import Workbook
from pandas import DataFrame, ExcelWriter


""" This is the code to get raw data from a specific Google Sheet"""
try:
    import argparse
    flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
    flags = None

# If modifying these scopes, delete your previously saved credentials
# at ~/.credentials/sheets.googleapis.com-python-quickstart.json
SCOPES = 'https://www.googleapis.com/auth/spreadsheets'
CLIENT_SECRET_FILE = 'client_secret_noemail.json'
APPLICATION_NAME = 'Google Sheets API Python'


def get_credentials():
    """Gets valid user credentials from storage.

    If nothing has been stored, or if the stored credentials are invalid,
    the OAuth2 flow is completed to obtain the new credentials.

    Returns:
        Credentials, the obtained credential.
    """
    home_dir = os.path.expanduser('~')
    credential_dir = os.path.join(home_dir, '.credentials')
    if not os.path.exists(credential_dir):
        os.makedirs(credential_dir)
    credential_path = os.path.join(credential_dir,
                                   'sheets.googleapis.com-python-quickstart.json')

    store = Storage(credential_path)
    credentials = store.get()
    if not credentials or credentials.invalid:
        flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
        flow.user_agent = APPLICATION_NAME
        if flags:
            credentials = tools.run_flow(flow, store, flags)
        else:  # Needed only for compatibility with Python 2.6
            credentials = tools.run_flow(flow, store)
        print('Storing credentials to ' + credential_path)
    return credentials


def main():
    """Shows basic usage of the Sheets API.

    Creates a Sheets API service object and prints the names and majors of
    students in a sample spreadsheet:
    https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
    """
    credentials = get_credentials()
    http = credentials.authorize(httplib2.Http())
    discoveryUrl = ('https://sheets.googleapis.com/$discovery/rest?version=v4')
    service = discovery.build(
        'sheets', 'v4', http=http, discoveryServiceUrl=discoveryUrl)

    # Google Sheet Url Link and Range name. Can use tab names to get full page.
    spreadsheetId = '[spreadsheetid]'
    rangeName = 'tblActiveEmployees'

    # TODO: Add desired entries to the request body if needed
    clear_values_request_body = {}

    # Building Service to Clear Google Sheet
    request = service.spreadsheets().values().clear(spreadsheetId=spreadsheetId,
                                                    range=rangeName, body=clear_values_request_body)
    response = request.execute()

    # Prints response that Google Sheet has been cleared
    responseText = '\n'.join(
        [str(response), 'The Google Sheet has been cleared!'])
    print(responseText)

    # SQL Server Connection
    server = '[SQLServerIP]'
    database = '[SQLServerDB]'
    username = '[SQLServerUserID]'
    password = '[SQLServerPW]'
    cnxn = pyodbc.connect('Driver={ODBC Driver 13 for SQL Server};SERVER=' +
                          server+';DATABASE='+database+';UID='+username+';PWD='+password)

    # Sample SQL Query to get Data
    sql = 'select * from tblActiveEmployees'
    cursor = cnxn.cursor()
    cursor.execute(sql)
    list(cursor.fetchall())

    # Pandas reading values from SQL query, and building table
    sqlData = pandas.read_sql_query(sql, cnxn)

    # Pandas building dataframe, and exporting .xlsx copy of table
    df = DataFrame(data=sqlData)

    df.to_excel('tblActiveEmployees.xlsx',
                header=True, index=False)
    dfListFormat = df.values.tolist()

    # How the input data should be interpreted.
    value_input_option = 'USER_ENTERED'  # TODO: Update placeholder value.

    # How the input data should be inserted.
    insert_data_option = 'OVERWRITE'  # TODO: Update placeholder value.

    value_range_body = {
        "majorDimension": "ROWS",
        "values": [
            [dfListFormat]
        ]
    }

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


if __name__ == '__main__':
    main()

多亏@tehhowch的输入,下面的内容能够解决我的问题。问题是我的数据已经在一个列表中,并将其用作
的“值”:[[dfListFormat]
使
的“值”
成为一个数组的数组,而不仅仅是一个数组的数组。简单地分配给
没有括号的“值”
,效果很好

下面是更新的代码,非常感谢tehhowch

from __future__ import print_function
import httplib2
import oauth2client
import os
import googleapiclient
import openpyxl
import pandas
import pyodbc

from googleapiclient import discovery
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage
from openpyxl import Workbook
from pandas import DataFrame, ExcelWriter


""" This is the code to get raw data from a specific Google Sheet"""
try:
    import argparse
    flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
    flags = None

# If modifying these scopes, delete your previously saved credentials
# at ~/.credentials/sheets.googleapis.com-python-quickstart.json
SCOPES = 'https://www.googleapis.com/auth/spreadsheets'
CLIENT_SECRET_FILE = 'client_secret_noemail.json'
APPLICATION_NAME = 'Google Sheets API Python'


def get_credentials():
    """Gets valid user credentials from storage.

    If nothing has been stored, or if the stored credentials are invalid,
    the OAuth2 flow is completed to obtain the new credentials.

    Returns:
        Credentials, the obtained credential.
    """
    home_dir = os.path.expanduser('~')
    credential_dir = os.path.join(home_dir, '.credentials')
    if not os.path.exists(credential_dir):
        os.makedirs(credential_dir)
    credential_path = os.path.join(credential_dir,
                                   'sheets.googleapis.com-python-quickstart.json')

    store = Storage(credential_path)
    credentials = store.get()
    if not credentials or credentials.invalid:
        flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
        flow.user_agent = APPLICATION_NAME
        if flags:
            credentials = tools.run_flow(flow, store, flags)
        else:  # Needed only for compatibility with Python 2.6
            credentials = tools.run_flow(flow, store)
        print('Storing credentials to ' + credential_path)
    return credentials


def main():
    """Shows basic usage of the Sheets API.

    Creates a Sheets API service object and prints the names and majors of
    students in a sample spreadsheet:
    https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
    """
    credentials = get_credentials()
    http = credentials.authorize(httplib2.Http())
    discoveryUrl = ('https://sheets.googleapis.com/$discovery/rest?version=v4')
    service = googleapiclient.discovery.build(
        'sheets', 'v4', http=http, discoveryServiceUrl=discoveryUrl)

    # Google Sheet Url Link and Range name. Can use tab names to get full page.
    spreadsheetId = '[spreadsheetID'
    rangeName = 'tblActiveEmployees'

    # TODO: Add desired entries to the request body if needed
    clear_values_request_body = {}

    # Building Service to Clear Google Sheet
    request = service.spreadsheets().values().clear(spreadsheetId=spreadsheetId,
                                                    range=rangeName, body=clear_values_request_body)
    response = request.execute()

    # Prints response that Google Sheet has been cleared
    responseText = '\n'.join(
        [str(response), 'The Google Sheet has been cleared!'])
    print(responseText)

    # SQL Server Connection
    server = '[SQLServerIP]'
    database = '[SQLServerDB]'
    username = '[SQLServerUserID]'
    password = '[SQLServerPW]'
    cnxn = pyodbc.connect('Driver={ODBC Driver 13 for SQL Server};SERVER=' +
                          server+';DATABASE='+database+';UID='+username+';PWD='+password)

    # Sample SQL Query to get Data
    sql = 'select * from tblActiveEmployees'
    cursor = cnxn.cursor()
    cursor.execute(sql)
    list(cursor.fetchall())

    # Pandas reading values from SQL query, and building table
    sqlData = pandas.read_sql_query(sql, cnxn)

    # Pandas building dataframe, and exporting .xlsx copy of table
    df = DataFrame(data=sqlData)

    df.to_excel('tblActiveEmployees.xlsx',
                header=True, index=False)
    dfHeaders = df.columns.values.tolist()
    dfHeadersArray = [dfHeaders]
    dfData = df.values.tolist()

    print(dfHeaders)
    print(dfData)

    # How the input data should be interpreted.
    value_input_option = 'USER_ENTERED'  # TODO: Update placeholder value.

    # How the input data should be inserted.
    insert_data_option = 'OVERWRITE'  # TODO: Update placeholder value.

    value_range_body = {
        "majorDimension": "ROWS",
        "values": dfHeadersArray + dfData
    }

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


if __name__ == '__main__':
    main()

您正在从
apiclient
googleapiclient
导入?我想您只需要使用
GoogleAppClient
。。。回复:您的问题,您是否打印/检查了数据中的
“值”:
属性?这似乎是你的问题,应该是的。啊,是的。。。API快速入门使用apiclient,我还看到googleapiclient是最新的版本?抢手货是的,根据你的建议,我把结果打印出来,看到它们已经排成一列了。尝试运行.py时删除了values部分周围的[],效果非常好。非常感谢你的帮助!所以,为了让我正确理解这一点,您是否将sql查询读入df并将其推送到Google工作表中?如果是这样,那真是太棒了,我会试试看!嘿@datanoveler,是的!这是正确的。我能够直接从我们的MSSQL服务器上阅读,并将其发布到谷歌表单。它一直工作得很好!