Как импортировать файл CSV с помощью Google Sheets API V4 - (без перезаписи существующих строк и пропуска дубликатов) - PullRequest
0 голосов
/ 01 мая 2020

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

Проблема:

API.spreadsheets().batchUpdate перезаписывает все существующие данные.

Цель:

Загрузка .csv данных в таблицы Google и пропуск уже существующих данных во избежание дублирования.

Ссылка на публикацию для загрузки файла CSV в Google Sheets

ПРИМЕЧАНИЕ. Я перешел к решению @Ufos

Итак, мой код:

"""
Getting an connection to Google Sheets API and imports a csv file into a sheet and inserts all new data. If
data already exists in file it will ignore it and ony insert data that is not already in the sheet.
"""

# import pickle
from googleapiclient.discovery import build
from google.oauth2.service_account import Credentials

try:
    # for Python2
    from Tkinter import *   ## notice capitalized T in Tkinter
    import tkFileDialog as filedialog
except ImportError:
    # for Python3
    from tkinter import *   ## notice lowercase 't' in tkinter here
    from tkinter import messagebox
    from tkinter import filedialog

import sys

SPREADSHEET_ID = ''  # TODO: Get this one from the link in browser
worksheet_name = ''  # TODO: Insert sheet name
# path_to_csv = ''

# path_to_credentials = 'Credentials/token.pickle'
#path_to_credentials = 'creds.json'

scopes = ["https://spreadsheets.google.com/feeds",
          'https://www.googleapis.com/auth/spreadsheets',
          "https://www.googleapis.com/auth/drive.file",
          "https://www.googleapis.com/auth/drive"]


# convenience routines
def find_sheet_id_by_name(sheet_name):
    # ugly, but works
    sheets_with_properties = API \
        .spreadsheets() \
        .get(spreadsheetId=SPREADSHEET_ID, fields='sheets.properties') \
        .execute() \
        .get('sheets')

    for sheet in sheets_with_properties:
        if 'title' in sheet['properties'].keys():
            if sheet['properties']['title'] == sheet_name:
                return sheet['properties']['sheetId']


def push_csv_to_gsheet(csv_path, sheet_id):
    with open(csv_path, 'r') as csv_file:
        csvContents = csv_file.read()
    body = {
        'requests': [{
            'pasteData': {
                "coordinate": {
                    "sheetId": sheet_id,
                    "rowIndex": "0",  # adapt this if you need different positioning
                    "columnIndex": "0", # adapt this if you need different positioning
                },
                "data": csvContents,
                "type": 'PASTE_NORMAL',
                "delimiter": ';',
            }
        }]
    }
    request = API.spreadsheets().batchUpdate(spreadsheetId=SPREADSHEET_ID, body=body)
    response = request.execute()
    return response


def get_csv_file():
    root_tk = Tk()
    root_tk.withdraw()
    user_prompt_file_path = filedialog.askopenfilename(title='Choose .csv file')  # // initialdir = "C:/<whatever>"
    if len(user_prompt_file_path) == 0:
        sys.exit("Stopped because no csv file was given")

    print(f'File path to csv is: {user_prompt_file_path}')
    return user_prompt_file_path


csv_file_path = get_csv_file()

# upload
# with open(path_to_credentials, 'rb') as token:
#     # credentials = pickle.load(token)
#     credentials = token.read()

credentials = Credentials.from_service_account_file("creds.json", scopes=scopes)

API = build('sheets', 'v4', credentials=credentials)

push_csv_to_gsheet(
    csv_path=csv_file_path,
    sheet_id=find_sheet_id_by_name(worksheet_name)
)

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

Пример данных:

В этом примере я импортирую sample_csv_01.CSV сначала запустив кодовые, после этого я получил новые фрукты, поэтому я снова запускаю код, выбирая sample_csv_02.CSV, и, поскольку я постоянно получаю новые фрукты, мне нужно снова запустить код с sample_csv_03.CSV. Результат, который я ищу после трехкратного выполнения кода с различными .CSV, приведен ниже в разделе Цель.

sample_csv_01.CSV

"Fruits"; "Amount"; "Price"; "Origin"
"Apple"; 4; 4.50; "America"
"Banana"; 18; 2.40; "Spain"

sample_csv_02.CSV

"Fruits"; "Amount"; "Price"; "Origin"
"Apple"; 4; 4.50; "America"
"Banana"; 18; 2.40; "Spain"
"Acerola"; 22; 1; "West Indian"
"Apricots;"; 2; 0.60; "Germany"
"Breadfruit"; 40; 3.50; "China"

sample_csv_03.CSV

"Fruits"; "Amount"; "Price"; "Origin"
"Banana"; 18; 2.40; "Spain"
"Blackberries"; 55; 0.23; "England"
"Acerola"; 22; 1; "West Indian"
"Carambola"; 4; 0; "Japan"
"Apricots;"; 2; 0.60; "Germany"
"Coconut Meat"; 32; 1.80; "Africa"

Таблица целей после импорта всех CSV-файлов с одинаковым сценарием в тот же лист.

"Fruits"; "Amount"; "Price"; "Origin"
"Acerola"; 22; 1; "West Indian"
"Apple"; 4; 4.50; "America"
"Apricots;"; 2; 0.60; "Germany"
"Banana"; 18; 2.40; "Spain"
"Blackberries"; 55; 0.23; "England"
"Breadfruit"; 40; 3.50; "China"
"Carambola"; 4; 0; "Japan"
"Coconut Meat"; 32; 1.80; "Africa"
...