Я пытаюсь преобразовать набор реляционных файлов .csv в базу данных с sqlite3:
import pandas as pd
import os
import csv
import sqlite3
dir = 'db_folder/'
dir2 = 'test/1/'
# Clean data
for file in os.listdir(dir):
if file.endswith(".csv"):
filename = os.path.splitext(os.path.basename(file))[0]
with open(f'{dir}{file}', encoding='utf8', errors='ignore') as f:
columns = list(filter(None, csv.DictReader(f).fieldnames))
df = pd.read_csv(f, low_memory=False)
clean = df.dropna(1, how='all')
path = r'./TEST/1/'
clean.to_csv(f'{path}{filename}.csv', header=columns, index=False)
# Create tables and insert data
conn = sqlite3.connect('test/mydatabase.db')
cursor = conn.cursor()
for file in os.listdir(dir2):
filename = os.path.splitext(os.path.basename(file))[0]
with open(f'{dir2}{file}', encoding='utf8', errors='ignore') as f:
columns = csv.DictReader(f).fieldnames
cursor.execute('DROP TABLE IF EXISTS "{table}"'.format(table=filename))
cursor.execute('CREATE TABLE "{table}" ( {columns} )'.format(
table=filename, columns=','.join('"{}"'.format(column) for column in columns)))
dr = csv.DictReader(f)
cursor.executemany('INSERT INTO "{table}" VALUES ( {values} )'.format(
table=filename, values=','.join('?' for column in columns)),
(list(map(row.get, columns)) for row in dr))
conn.commit()
cursor.close()
conn.close()
Это выполняется без ошибок и создает базу данных с правильными таблицами с правильными столбцами. Однако по какой-то причине строки все NULL.
Я попытался отладить строку вставки, чтобы увидеть, что происходит. Я вошел в функцию executemany()
. Внутри переменной DictReader находился список имен полей ['2', '383', '0.5019', '2003-08-12']
, который действительно является одной из строк, принадлежащих таблице. Я не могу понять, почему он вставлен в мою базу данных как NULL.