Cómo escribir el dataframe de Pandas en sqlite con Index

Tengo una lista de datos de bolsa extraídos de Yahoo en un DataFrame de pandas (ver formato a continuación). La fecha sirve como índice en el dataframe. Quiero escribir los datos (incluido el índice) en una base de datos SQLite.

AAPL GE Date 2009-01-02 89.95 14.76 2009-01-05 93.75 14.38 2009-01-06 92.20 14.58 2009-01-07 90.21 13.93 2009-01-08 91.88 13.95 

Según mi lectura del código write_frame para Pandas, actualmente no es compatible con la escritura del índice . Intenté usar to_records en su lugar, pero encontré el problema con Numpy 1.6.2 y datetimes . Ahora estoy tratando de escribir tuplas usando .itertuples, pero SQLite produce un error que indica que el tipo de datos no es compatible (consulte el código y el resultado a continuación). Soy relativamente nuevo en Python, Pandas y Numpy, así que es completamente posible que me esté perdiendo algo obvio. Creo que tengo un problema al intentar escribir una fecha y hora en SQLite, pero creo que podría ser una complicación excesiva.

Creo que puedo solucionar el problema actualizando a Numpy 1.7 o la versión de desarrollo de Pandas, que tiene una solución publicada en GitHub. Preferiría desarrollar utilizando versiones de lanzamiento de software; soy nuevo en esto y no quiero que los problemas de estabilidad confundan aún más las cosas.

¿Hay alguna manera de lograr esto usando Python 2.7.2, Pandas 0.10.0 y Numpy 1.6.2? Tal vez la limpieza de las fechas de alguna manera? Estoy un poco por encima de mi cabeza, cualquier ayuda sería apreciada.

Código:

 import numpy as np import pandas as pd from pandas import DataFrame, Series import sqlite3 as db # download data from yahoo all_data = {} for ticker in ['AAPL', 'GE']: all_data[ticker] = pd.io.data.get_data_yahoo(ticker, '1/1/2009','12/31/2012') # create a data frame price = DataFrame({tic: data['Adj Close'] for tic, data in all_data.iteritems()}) # get output ready for database export output = price.itertuples() data = tuple(output) # connect to a test DB with one three-column table titled "Demo" con = db.connect('c:/Python27/test.db') wildcards = ','.join(['?'] * 3) insert_sql = 'INSERT INTO Demo VALUES (%s)' % wildcards con.executemany(insert_sql, data) 

Resultado:

 --------------------------------------------------------------------------- InterfaceError Traceback (most recent call last)  in () ----> 1 con.executemany(insert_sql, data) InterfaceError: Error binding parameter 0 - probably unsupported type. 

En pandas recientes, el índice se guardará en la base de datos (solía tener que reset_index primero).

Siguiendo los documentos (configurando una conexión SQLite en memoria):

 import sqlite3 # Create your connection. cnx = sqlite3.connect(':memory:') 

Nota: También puede pasar un motor SQLAlchemy aquí (ver el final de la respuesta).

Podemos ahorrar price2 a cnx :

 price2.to_sql(name='price2', con=cnx) 

Podemos recuperar a través de read_sql :

 p2 = pd.read_sql('select * from price2', cnx) 

Sin embargo, cuando las fechas almacenadas (y recuperadas) son unicode lugar de Timestamp de Timestamp . Para volver a convertir lo que empezamos, podemos usar pd.to_datetime :

 p2.Date = pd.to_datetime(p2.Date) p = p2.set_index('Date') 

Recuperamos el mismo DataFrame que los prices :

 In [11]: p2 Out[11]:  DatetimeIndex: 1006 entries, 2009-01-02 00:00:00 to 2012-12-31 00:00:00 Data columns: AAPL 1006 non-null values GE 1006 non-null values dtypes: float64(2) 

También puedes usar un motor SQLAlchemy :

 from sqlalchemy import create_engine e = create_engine('sqlite://') # pass your db url price2.to_sql(name='price2', con=cnx) 

Esto le permite usar read_sql_table (que solo se puede usar con SQLAlchemy):

 pd.read_sql_table(table_name='price2', con=e) # Date AAPL GE # 0 2009-01-02 89.95 14.76 # 1 2009-01-05 93.75 14.38 # 2 2009-01-06 92.20 14.58 # 3 2009-01-07 90.21 13.93 # 4 2009-01-08 91.88 13.95 

Desafortunadamente, pandas.io.write_frame ya no existe en las versiones más recientes de Pandas con respecto a la respuesta actual aceptada. Por ejemplo estoy usando pandas 0.19.2. Puedes hacer algo como

 from sqlalchemy import create_engine disk_engine = create_engine('sqlite:///my_lite_store.db') price.to_sql('stock_price', disk_engine, if_exists='append') 

Y luego, a su vez, previsualiza tu tabla con lo siguiente:

 df = pd.read_sql_query('SELECT * FROM stock_price LIMIT 3',disk_engine) df.head() 

A continuación se muestra el código que funcionó para mí. Pude escribirlo en SQLite DB.

 import pandas as pd import sqlite3 as sq data =  sql_data = 'D:\\SA.sqlite' #- Creates DB names SQLite conn = sq.connect(sql_data) cur = conn.cursor() cur.execute('''DROP TABLE IF EXISTS SA''') data.to_sql('SA', conn, if_exists='replace', index=False) # - writes the pd.df to SQLIte DB pd.read_sql('select * from SentimentAnalysis', conn) conn.commit() conn.close()