¿Cómo transformar un CSV enorme en SQLite usando Pandas?

Tengo una gran mesa (alrededor de 60 GB) en forma de un archivo CSV archivado. Quiero transformarlo en un archivo SQLite.

Lo que hago en este momento en lo siguiente:

import pandas import sqlite3 cnx = sqlite3.connect('db.sqlite') df = pandas.read_csv('db.gz', compression='gzip') df.to_sql('table_name', cnx) 

Funciona bien para archivos más pequeños, pero con los archivos grandes tengo problemas de memoria. El problema es que los pandas leen toda la tabla en la memoria (RAM) y luego la guardan en el archivo SQLite.

¿Hay una solución elegante a este problema?

Esto va a ser problemático con los pandas debido a su tamaño. Cualquier razón por la que no pueda usar el módulo csv y simplemente recorrer el archivo.

Idea básica (sin probar):

 import gzip import csv import sqlite3 with gzip.open('db.gz') as f, sqlite3.connect('db.sqlite') as cnx: reader = csv.reader(f) c = cnx.cursor() c.executemany('insert into table_name values (?,?,...)', reader) 

No he hecho ningún trabajo con CSV de ese tamaño, pero parece que el tipo de cosas que Odo podría resolver rápidamente.

Realicé una comprobación preliminar de los documentos y parece que escribieron algo sobre el tema del análisis de CSV de mayor tamaño que la memoria en las bases de datos SQL que llaman específicamente a SQLite3 como destino.

Aquí está el ejemplo que publican para analizar un archivo de texto de 33 GB.

 In [1]: dshape = discover(resource('all.csv')) In [2]: %time t = odo('all.no.header.csv', 'sqlite:///db.db::nyc', ...: dshape=dshape) CPU times: user 3.09 s, sys: 819 ms, total: 3.91 s Wall time: 57min 31s 

[Actualización a 06-15-2017]

Parece que csv2sqlite.py puede ser el camino a seguir con SQLite. Definitivamente, Chuck-by-Chuck es demasiado lento para archivos grandes (> 1GB). Cuando probé 6.5GB de nyc311calls.csv con csv2sqlite.py, solo tomó ~ 24 minutos crear un archivo de base de datos SQLite con adivinación de tipo de datos. 24 minutos es similar al tiempo de gasto de MySQL con “LOAD DATA INFILE”. Esto no es malo, aunque es posible que deba cambiar el tipo de datos para algunas de las columnas. En mi opinión, usar csv2sqlite.py es el método más eficiente en el tiempo para crear un archivo de base de datos SQLite desde un archivo csv ahora mismo.

1) Descargue un archivo csv2sqlite.py desde aquí y colóquelo en el directorio que contiene un archivo csv.

2) Al usar Windows Prompt , vaya al directorio que contiene el csv2sqlite.py y el archivo csv (por ejemplo, nyc311calls.csv) que desea importar.

3) Ejecute el código de python csv2sqlite.py nyc311calls.csv database_name.db y espere. Nota: Python PATH debe incluirse en sus Windows Environment Variables .


Esta es una pequeña búsqueda antigua, pero parece que nadie dio las respuestas claras. Espero que mi respuesta te ayude. Con Sqlite te recomiendo que veas este sitio , que te da la idea y lo que debes hacer, una carga por partes. Probé varios enfoques, pero hasta ahora esta es la forma más confiable en mi opinión.

El procedimiento básico es así: 1) Importe una pequeña porción de la mesa grande a los pandas. 2) Procesar y cargarlos a SQLite. 3) Mantener para continuar este proceso.

Subí un procedimiento más detallado de lo que hice aquí (archivo Jupyter) si está interesado. Puede encontrar los datos de la llamada NYC311 aquí

Algunos comentarios de mi parte.

1) El paquete Odo no funciona completamente si los datos incluyen las cadenas vacías. Espero que puedan mejorar estas cuestiones. es decir, si los datos están muy limpios y bien organizados, el paquete Odo podría ser la opción.

2) El enfoque anterior es un trabajo que consume mucho tiempo. Especialmente, una mesa de ~ 6GB toma más de 24 horas. Porque los pandas son lentos.

3) Si no se apega a SQLite, diría que MySQL con “LOAD DATA INFILE” es una buena opción para usted. Usted puede encontrar cómo hacerlo con la búsqueda en Internet. Siempre y cuando lo probé, esta es una manera muy confiable y eficiente. Más tarde, puede convertir a sqlite si realmente necesita usar sqlite. Especialmente, si los datos tienen muchas cadenas vacías y columnas de fecha y hora, que son necesarias para convertirlas al tipo de fecha y hora, definitivamente uso MySQL.