From b78b18bbb97fa29d784a7cab0ea1f51ba4df039e Mon Sep 17 00:00:00 2001 From: Adam Greenhall Date: Sat, 18 Jul 2015 13:44:53 -0700 Subject: [PATCH 1/2] support sqlalchemy sessions --- pandas/io/sql.py | 6 +++--- pandas/io/tests/test_sql.py | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/pandas/io/sql.py b/pandas/io/sql.py index ef8360f0ff459..540695721ac13 100644 --- a/pandas/io/sql.py +++ b/pandas/io/sql.py @@ -62,7 +62,7 @@ def compile_big_int_sqlite(type_, compiler, **kw): if _SQLALCHEMY_INSTALLED: import sqlalchemy - return isinstance(con, sqlalchemy.engine.Connectable) + return isinstance(con, sqlalchemy.engine.Connectable) or isinstance(con, sqlalchemy.orm.session.Session) else: return False @@ -362,7 +362,7 @@ def read_sql_query(sql, con, index_col=None, coerce_float=True, params=None, ---------- sql : string SQL query to be executed - con : SQLAlchemy connectable(engine/connection) or sqlite3 DBAPI2 connection + con : SQLAlchemy connectable(engine/connection/session) or sqlite3 DBAPI2 connection Using SQLAlchemy makes it possible to use any DB supported by that library. If a DBAPI2 object, only sqlite3 is supported. @@ -420,7 +420,7 @@ def read_sql(sql, con, index_col=None, coerce_float=True, params=None, ---------- sql : string SQL query to be executed or database table name. - con : SQLAlchemy connectable(engine/connection) or DBAPI2 connection (fallback mode) + con : SQLAlchemy connectable(engine/connection/session) or DBAPI2 connection (fallback mode) Using SQLAlchemy makes it possible to use any DB supported by that library. If a DBAPI2 object, only sqlite3 is supported. diff --git a/pandas/io/tests/test_sql.py b/pandas/io/tests/test_sql.py index d95babff2653b..4e88b35135276 100644 --- a/pandas/io/tests/test_sql.py +++ b/pandas/io/tests/test_sql.py @@ -918,6 +918,30 @@ def test_sqlalchemy_type_mapping(self): table = sql.SQLTable("test_type", db, frame=df) self.assertTrue(isinstance(table.table.c['time'].type, sqltypes.DateTime)) + def test_session(self): + """ + read_sql_query should work within a session. + a temporary table created within the session should be able to be queried. + """ + from sqlalchemy.orm import sessionmaker + session = sessionmaker(bind=self.conn)() + # create a temporary table within a session + # this is contrived example or a temporary tables but they can be really useful + session.execute("""CREATE TEMPORARY TABLE temp_iris AS SELECT * FROM iris LIMIT 5""") + # read_sql_query can read from the temporary table + iris_frame = sql.read_sql_query("SELECT * FROM temp_iris", session) + assert(len(iris_frame) == 5) + + def test_session_close(self): + """read_sql_query shouldn't close the session""" + from sqlalchemy.orm import sessionmaker + session = sessionmaker(bind=self.conn)() + session.execute("""CREATE TEMPORARY TABLE temp_iris AS SELECT * FROM iris LIMIT 5""") + sql.read_sql_query("SELECT count(1) FROM temp_iris", session) + # run again to test that the session hasn't been closed by the last call + iris_frame = sql.read_sql_query("SELECT * FROM temp_iris", session) + assert(len(iris_frame) == 5) + class _EngineToConnMixin(object): """ From d889838d2748df9410d062091a81dcf8cfc397c6 Mon Sep 17 00:00:00 2001 From: Adam Greenhall Date: Sat, 18 Jul 2015 19:13:10 -0700 Subject: [PATCH 2/2] support old sqlalchemy versions --- pandas/io/sql.py | 6 +++++- pandas/io/tests/test_sql.py | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/pandas/io/sql.py b/pandas/io/sql.py index 540695721ac13..f0f8897db3f26 100644 --- a/pandas/io/sql.py +++ b/pandas/io/sql.py @@ -62,7 +62,11 @@ def compile_big_int_sqlite(type_, compiler, **kw): if _SQLALCHEMY_INSTALLED: import sqlalchemy - return isinstance(con, sqlalchemy.engine.Connectable) or isinstance(con, sqlalchemy.orm.session.Session) + is_connectable = isinstance(con, sqlalchemy.engine.Connectable) + if sqlalchemy.__version__ >= '1.0.0': + # support sessions, if sqlalchemy version has them + is_connectable |= isinstance(con, sqlalchemy.orm.session.Session) + return is_connectable else: return False diff --git a/pandas/io/tests/test_sql.py b/pandas/io/tests/test_sql.py index 4e88b35135276..43f6e65adf35d 100644 --- a/pandas/io/tests/test_sql.py +++ b/pandas/io/tests/test_sql.py @@ -923,6 +923,8 @@ def test_session(self): read_sql_query should work within a session. a temporary table created within the session should be able to be queried. """ + if sqlalchemy.__version__ < '1.0.0': + nose.SkipTest('session requires sqlalchemy>=1.0.0') from sqlalchemy.orm import sessionmaker session = sessionmaker(bind=self.conn)() # create a temporary table within a session @@ -934,6 +936,8 @@ def test_session(self): def test_session_close(self): """read_sql_query shouldn't close the session""" + if sqlalchemy.__version__ < '1.0.0': + nose.SkipTest('session requires sqlalchemy>=1.0.0') from sqlalchemy.orm import sessionmaker session = sessionmaker(bind=self.conn)() session.execute("""CREATE TEMPORARY TABLE temp_iris AS SELECT * FROM iris LIMIT 5""")