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