2015-04-08 43 views
44

Questo argomento non è stato risolto in un momento, qui o altrove. Esiste una soluzione per convertire SQLAlchemy <Query object> in un DataFrame panda?SQLAlchemy Conversione ORM in panda DataFrame

Pandas ha la capacità di utilizzare pandas.read_sql ma ciò richiede l'utilizzo di SQL raw. Ho due ragioni per voler evitarlo: 1) ho già tutto usando l'ORM (un buon motivo in sé e per sé) e 2) sto usando gli elenchi python come parte della query (es .: .db.session.query(Item).filter(Item.symbol.in_(add_symbols) dove Item è il mio model class e add_symbols è una lista). Questo è l'equivalente di SQL SELECT ... from ... WHERE ... IN.

È possibile qualcosa?

risposta

82

seguito dovrebbe funzionare nella maggior parte dei casi:

df = pd.read_sql(query.statement, query.session.bind) 

Vedi pandas.read_sql documentazione per ulteriori informazioni sui parametri.

+26

Oh. Mio. Dio. Abbiamo fatto molta strada. – dmvianna

+0

@van +1 ma potrebbe fare con un po 'più di dettaglio. per esempio. Ho fatto 'df = pd.read_sql (query, query.bind)' quando 'query' è un' sqlalchemy.sql.selectable.Select'. Altrimenti, ho ottenuto che l'oggetto "Seleziona" non ha attributo "sessione". – josh

+0

Per copiare e incollare, ho aggiunto il link alla documentazione direttamente nella risposta, che copre la tua domanda: dovresti fornire il parametro 'con', che può essere' engine' o 'connection string' – van

0

Se vuoi compilare una query con parametri e argomenti specifici dialettali, usare qualcosa di simile:

c = query.statement.compile(query.session.bind) 
df = pandas.read_sql(c.string, query.session.bind, params=c.params) 
21

solo per rendere questo più chiaro per panda inesperti programmatori, ecco un esempio concreto,

pd.read_sql(session.query(Complaint).filter(Complaint.id == 2).statement,session.bind) 

Qui selezioniamo una denuncia da tavolo reclami (modello sqlalchemy è Complaint) con id = 2

+0

Penso che questo sia più chiaro, quando il codice è basato su ORM. – user40780

+0

OMG! Ho faticato molto con sqlAlchemy. Solo una nota a margine qui: puoi anche scrivere read_sql ('SELECT * FROM TABLENAME', db.session.bind). Grazie. La risposta di cui sopra mi ha aiutato più di quella accettata. – PallavBakshi

+0

Cosa fa '.statement'? – cardamom

2

La soluzione scelta non ha funzionato per me, come ho continuato a get ting l'errore

AttributeError: 'AnnotatedSelect' object has no attribute 'lower'

ho trovato il seguente lavorato:

df = pd.read_sql_query(query.statement, engine)