Dav*_*idJ 10 sql sqlalchemy netezza python-2.7 pandas
我正在将Python代码转换为新的基于SQLAlchemy的Pandas 0.14.1.
我们使用的常见模式是(通用):
connection = db.connect() # open connection/session
sql = 'CREATE TEMP TABLE table1 AS SELECT ...'
connection.execute(sql)
... other sql that creates TEMP tables from various joins of previous TEMP tables ...
sql = 'CREATE TEMP TABLE tableN AS SELECT ...'
connection.execute(sql)
result = connection.query('SELECT * FROM tableN WHERE ...')
connection.close()
Run Code Online (Sandbox Code Playgroud)
现在,一旦连接关闭,TEMP表就会被DB服务器清除.但是,由于最终的选择查询使用相同的连接/会话,因此它可以访问表.
如何使用SQLAlchemy和pd.read_sql_query()实现类似?
例如:
engine = sqlalchemy.create_engine('netezza://@mydsn')
connection = engine.connect()
sql = 'CREATE TEMP TABLE tmptable AS SELECT ...'
connection.execute(sql)
result = pd.read_sql_query('SELECT * FROM tmptable WHERE ...', engine)
Run Code Online (Sandbox Code Playgroud)
产生一个DB错误,TEMP表tmptable不存在.可能这是因为将引擎传递给read_sql_query()需要它打开一个具有独立会话范围的新连接,因此无法看到TEMP表.这是一个合理的假设吗?
有办法解决这个问题吗?(不支持将连接传递给read_sql_query())
(我知道我可以将SQL连接成一个单独的字符串;分隔语句,但这是对实际情况的简化,其中TEMP表由多个函数创建,这些函数调用其他嵌套3-4深.所以,实现这一目标需要实现一个层,而不是在发出之前将SQL合并到多个调用之间,如果有更好的方法,我宁愿避免实现
使用 -
熊猫:0.14.1 sqlalchemy
:0.9.7
pyodbc:3.0.6
Win7 x86_64 Canopy Python发行版(Python 2.7.6)
Josh Kuhn的Netezza SQLAlchemy方言来自https://github.com/deontologician/netezza_sqlalchemy
小智 8
您需要做的就是在查询的开头添加“SET NOCOUNT ON”,这样 pandas read_sql 就会将所有内容作为一条语句读取。
sSQL = '''SET NOCOUNT ON
CREATE TABLE ...... '''
Run Code Online (Sandbox Code Playgroud)
小智 5
您现在可以将 SQLAlchemy 连接到pandas.read_sql. 从文档:
pandas.read_sql(sql, con, index_col=None, coerce_float=True, params=None, parse_dates=None, columns=None, chunksize=None)
...
con :SQLAlchemy 可连接(引擎/连接)或数据库字符串 URI
或 DBAPI2 连接(回退模式)
使用 SQLAlchemy 可以使用该 > 库支持的任何数据库。如果是 DBAPI2 对象,则仅支持 sqlite3。
所以,这应该有效:
engine = sqlalchemy.create_engine('netezza://@mydsn')
connection = engine.connect()
sql = 'CREATE TEMP TABLE tmptable AS SELECT ...'
connection.execute(sql)
result = pd.read_sql('SELECT * FROM tmptable WHERE ...', con=connection)
Run Code Online (Sandbox Code Playgroud)