to_sql read if_exists python sqlite3 pandas

python - read - pandas to_sql mysql



Cómo escribir el marco de datos Pandas en sqlite con Index (3)

Tengo una lista de los datos del mercado de valores extraídos de Yahoo en un DataFrame de pandas (ver formato a continuación). La fecha sirve como el í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? ¿Quizás limpiando las fechas de alguna manera? Estoy en 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) <ipython-input-15-680cc9889c56> in <module>() ----> 1 con.executemany(insert_sql, data) InterfaceError: Error binding parameter 0 - probably unsupported type.


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 = <This is going to be your pandas dataframe> 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()


Como mencionó, en el momento en que guarda el índice, pero lo que podemos hacer es reset_index , guardando el índice antiguo como una columna ( ''Date'' ).

price2 = price.reset_index() In [11]: price2 Out[11]: <class ''pandas.core.frame.DataFrame''> Int64Index: 1006 entries, 0 to 1005 Data columns: Date 1006 non-null values AAPL 1006 non-null values GE 1006 non-null values dtypes: datetime64[ns](1), float64(2)

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

import sqlite3 from pandas.io import sql # Create your connection. cnx = sqlite3.connect('':memory:'')

Podemos ahorrar price2 a cnx :

sql.write_frame(price2, name=''price2'', con=cnx)

Podemos recuperar a través de read_frame :

p2 = sql.read_frame(''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 comenzamos, podríamos apply Timestamp de Timestamp a la columna y a set_index :

from pandas.lib import Timestamp p2.Date = p2.Date.apply(Timestamp) p = p2.set_index(''Date'')

Recuperamos el mismo DataFrame que los prices :

In [20]: p Out[20]: <class ''pandas.core.frame.DataFrame''> 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)


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 previsualice su tabla con lo siguiente:

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