CSV до SQL, но все значения NULL - PullRequest
1 голос
/ 12 июля 2020

Я пытаюсь преобразовать набор реляционных файлов .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.

1 Ответ

0 голосов
/ 12 июля 2020

(list(map(row.get, columns)) for row in dr)) создает объект-генератор, но executemany принимает последовательность последовательностей. Вместо этого вам нужно [list(map(row.get, dr.fieldnames)) for row in dr], [] вместо ().

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