pandas.read_sql_query()如何查询TEMP表?

时间:2014-10-09 19:37:57

标签: sql python-2.7 pandas sqlalchemy netezza

我正在将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()

现在,一旦连接关闭,数据库服务器就会清除TEMP表。但是,由于最终的选择查询使用相同的连接/会话,因此它可以访问表。

如何使用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)

产生一个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)
来自https://github.com/deontologician/netezza_sqlalchemy

的Josh Kuhn的Netezza SQLAlchemy方言

5 个答案:

答案 0 :(得分:1)

您现在可以将可连接的SQLAlchemy传递给pandas.read_sql。来自docs

  

pandas.read_sql(sql,con,index_col = None,coerce_float = True,params = None,parse_dates = None,column = 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)

答案 1 :(得分:1)

您需要做的就是在查询开始时添加'SET NOCOUNT ON',这样pandas read_sql会将所有内容作为一条语句读取。

sSQL = '''SET NOCOUNT ON
CREATE TABLE ...... '''

答案 2 :(得分:0)

您使用的是Python和Netezza,我使用的是R和SQL Server,因此可能会有所不同。在我的脚本中,我遇到了类似的问题。 T-SQL中的sp_execute_external_script允许外部代码在数据库上运行,只允许select语句。这对我来说很麻烦,因为我想运行一个存储过程来创建一个临时表来进行选择。或者,我可以使用公用表表达式,联合等。可能值得进一步调查。

答案 3 :(得分:0)

我了解此问题,但是创建常规表不起作用吗?您可以在会话结束时提出诸如CREATE TABLE TEMP_t1' etc., and DROP`之类的约定。

答案 4 :(得分:0)

正如@ssharma所说,您现在可以将可连接的SQLAlchemy传递给pandas.read_sql。 如果您与会话创建者创建会话,则需要连接对象。

要读取未提交的更改,必须使用以下相同的连接:

engine = sqlalchemy.create_engine('netezza://@mydsn')
session = sessionmaker(bind=self.engine)()

sql = 'CREATE TEMP TABLE tmptable AS SELECT ...'
session.execute(sql)

result = pd.read_sql('SELECT * FROM tmptable WHERE ...', con=session.connection())