2015-04-08 15 views
44

Dieses Thema wurde schon lange nicht mehr angesprochen, hier oder anderswo. Gibt es eine Lösung, die einen SQLAlchemy <Query object> in einen Pandas DataFrame konvertiert?SQLAlchemy ORM Umwandlung in Pandas DataFrame

Pandas hat die Fähigkeit, pandas.read_sql zu verwenden, aber dies erfordert die Verwendung von Raw SQL. Ich habe zwei Gründe dafür, es zu vermeiden: 1) Ich habe bereits alles mit dem ORM (ein guter Grund an sich) und 2) Ich benutze Python-Listen als Teil der Abfrage (zB: .db.session.query(Item).filter(Item.symbol.in_(add_symbols) wo Item ist meine Modellklasse und add_symbols ist eine Liste). Dies entspricht SQL SELECT ... from ... WHERE ... IN.

Ist alles möglich?

Antwort

82

Unten sollte in den meisten Fällen funktionieren:

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

pandas.read_sql Dokumentation zu den Parametern für weitere Informationen.

+26

Oh. Meine. Gott. Wir sind von weit hergekommen. – dmvianna

+0

@van +1 könnte aber mit ein wenig mehr Detail machen. z.B. Ich habe 'df = pd.read_sql (query, query.bind)' wenn 'query' ein' sqlalchemy.sql.selectable.Select' ist. Ansonsten habe ich "Select" -Objekt hat kein Attribut "Sitzung". – josh

+0

Um zu kopieren-einfügen, habe ich Link zu der Dokumentation direkt in der Antwort, die Ihre Frage deckt: Sie sollten die 'con' Parameter, die die' engine' oder 'connection string' – van

0

Wenn Sie eine Abfrage mit Parametern und Dialekt spezifischen Argumente kompilieren wollen, verwenden Sie so etwas wie dieses:

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

Nur um dies deutlicher für Anfänger Pandas Programmierer, hier ist ein konkretes Beispiel,

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

Hier haben wir eine Beschwerde von Beschwerden Tabelle auswählen (sqlalchemy Modell ist Beschwerde) mit id = 2

+0

Ich denke, das ist klarer, wenn der Code ORM basiert. – user40780

+0

OMG! Ich habe viel mit sqlAlchemy Hell gekämpft. Nur eine Randnotiz: Sie können auch read_sql ('SELECT * FROM TABLENAME', db.session.bind) schreiben. Vielen Dank. Die obige Antwort hat mir mehr als die akzeptierte geholfen. – PallavBakshi

+0

Was macht '.statement'? – cardamom

2

Die gewählte Lösung nicht für mich arbeiten, wie ich immer get ting der Fehler

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

fand ich die bearbeitete folgende:

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