Я пытаюсь загрузить файл .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"