Как объединить две таблицы SQLite в python с помощью оператора UNION (в настоящее время выдается сообщение об ошибке «ValueError: параметры неподдерживаемого типа») - PullRequest
1 голос
/ 09 мая 2019

Я совершенно новичок как в python, так и в sqlite, поэтому, пожалуйста, потерпите меня, так как мой подход, безусловно, полностью загружен!Я пытаюсь добавить несколько файлов CSV в существующую таблицу в базе данных sqlite3 с помощью Python 3.6.Код, который я написал, объединяет отдельные CSV-файлы в один фрейм данных Pandas, который я затем очищаю, добавляя / комбинируя / удаляя столбцы, чтобы они соответствовали столбцам внутри фрейма данных sqlite.Затем он экспортирует новый фрейм данных в виде CSV-файла.Мне удалось добавить этот новый CSV-файл в существующую базу данных, создав новую таблицу в базе данных.Я хочу добавить данные из новой таблицы в существующую таблицу в базе данных, поэтому я попытался использовать оператор UNION, но он возвращает следующую ошибку «ValueError: параметры неподдерживаемого типа».Я знаю, что когда я смотрю на новую таблицу, которую я создал в базе данных, некоторые из столбцов имеют тип «REAL» вместо текста (несмотря на преобразование их всех в «str» перед экспортом CSV), в то время как все столбцы в таблицеЯ хочу объединиться, используя UNION, типа «TEXT», поэтому я подозреваю, что это или сам оператор UNION является проблемой, но я не уверен, что и как не исправить.Любая помощь с благодарностью!

import sqlite3 import os import pandas в виде pd import numpy as np

def add_CO2_files_to_database (files = None):

# If a list of filepaths isn't specified, use every csv file in the same
# directory as the script
if files is None:

    # Get the current directory
    cwd = os.getcwd()

    #Add every csv file that starts with 'FD_' to a list
    files = [cwd+'\\'+f for f in os.listdir(cwd) if f.startswith('FD_')]

#Merge the csv files above into single pandas data frame and add a column 
for file in files:

    df = pd.concat([pd.read_csv(fp).assign(file_name=os.path.basename(fp).split('.')[0]) for fp in files])

    #Create a new column called 'FD_serial' from the 'file_name' column 
    #that consists of just the FD serial number
    df['FD_serial'] = df['file_name'].str[0:11]

    #Create another column that combines the 'Day', 'Month', and 'Year' 
    #columns into 1 column called 'date'
    df['date'] = df['Month'].map(str)+'-'+df['Day'].map(str)+'-'+df['Year'].map(str)  

    #Combine columns 'date' and 'Time' into a column called 'date_time'
    #then convert column to datetime format
    df['date_time'] = pd.to_datetime(df['date'] + ' '+ df['Time'])

    #Create new column called 'id' that combines the FD serial number 
    #'FD_serial' and the timestamp 'date_time' so each line of data has a 
    #unique identifier in the database
    df['id'] = df['FD_serial'].map(str) + '_' + df['date'].map(str) + '_' + df['Time'].map(str)

    #Add column 'location' and populate with 'NaN'
    df['location'] = np.nan

    #Delete unneccesary columns: 'Month', 'Day', 'Year', 'Time', 'date', 'file_name'
    df = df.drop(["Month", "Day", "Year", "Time", "date", "file_name", "Mode"], axis=1)

    #Rename columns to match the SQLite database conventions
    df = df.rename({'Flux':'CO2_flux', 'Temperature (C)':'temp', 'CO2 Soil (ppm) ':'soil_CO2', 'CO2 Soil STD (ppm)':'soil_STD',
               'CO2 ATM (ppm)':'atm_CO2', 'CO2 ATM STD (ppm)':'atm_std'}, axis='columns')

    #Change data types of all columns to 'str' so it matches the data type in the database
    df = df.astype(str)

    #Save the merged data frame in a csv file called 'FD_CO2_data.csv'
    df.to_csv("FD_CO2_data.csv", index=False)

РАЗДЕЛ КОДА НИЖЕ ДОБАВЛЯЕТ ФАЙЛ CSVСОЗДАНО ВЫШЕ К БАЗЕ ДАННЫХ

#Connect to the SQLite Database and create a cursor   
conn = sqlite3.connect("email_TEST.db")
cur = conn.cursor()

#Read in the csv file 'FD_CO2_data.csv' that was created above
df = pd.read_csv('FD_CO2_data.csv')

#Add the csv file to the database as a new table
df.to_sql('FD_CO2', conn, if_exists='append', index=False)

#df_db = pd.read_sql_query("select * from FD_CO2 limit 5;", conn)
cur.execute("SELECT id, FD_serial, date_time, CO2_flux, temp, Soil_CO2, soil_STD, atm_CO2, atm_STD, location  FROM CO2 UNION SELECT id, FD_serial, date_time, CO2_flux, temp, Soil_CO2, soil_STD, atm_CO2, atm_STD, location FROM FD_CO2", conn)

print (df_db)

add_CO2_files_to_database ()

1 Ответ

1 голос
/ 10 мая 2019

Вставка строк из новой таблицы в существующую таблицу должна быть такой же простой, как

cur.execute("INSERT into CO2 select * from FD_CO2")

Предполагается, что столбцы в FD_CO2 отображаются непосредственно на столбцы в CO2 и не будет конфликтов вставки, например, дубликат ключа. Вам потребуется cur.commit() для фиксации строк в базе данных

A UNION в sqlite - сложный запрос, по сути, он такой же, как объединение в математике; он возвращает СОЮЗ из двух «наборов», то есть выбирает.

Ошибка "ValueError: parameters are of unsupported type" из-за аргумента conn для execute. Выполнение принимает аргументы, когда оператор sql параметризован, то есть принимает аргументы. Вот документация на эту тему по питону.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...