pymssql(python 模块)无法使用临时表

Posted

技术标签:

【中文标题】pymssql(python 模块)无法使用临时表【英文标题】:pymssql ( python module ) unable to use temporary tables 【发布时间】:2012-01-09 23:44:41 【问题描述】:

这不是一个问题,而是一个先发制人的答案。 (我从这个网站得到了很多帮助并想回馈。)

当我尝试使用 pymssql 通过 python 运行它时,我遇到了大量的 SQL 查询失败,但直接通过 MS SQL 时运行良好。 (例如,在我的例子中,我使用 MS SQL Server Management Studio 在 python 之外运行它。)

然后我终于发现了问题:pymssql不能处理临时表。至少不是我的版本,它仍然是 1.0.1。

作为证据,这是我的代码的 sn-p,稍作改动以保护任何 IP 问题:

conn = pymssql.connect(host=sqlServer, user=sqlID, password=sqlPwd, \
                       database=sqlDB)
cur = conn.cursor()
cur.execute(testQuery)

如果我用testQuery 定义如下调用,上面的代码失败(具体来说,不返回任何数据,如果你调用cur.fetchone(),则会吐出错误“pymssql.OperationalError: No data available.”):

testQuery = """
CREATE TABLE #TEST (
[sample_id] varchar (256)
,[blah] varchar (256) )
INSERT INTO #TEST
SELECT DISTINCT
        [sample_id]
        ,[blah]
FROM [myTableOI]
WHERE [Shipment Type] in ('test')

SELECT * FROM #TEST
"""

但是,如果testQuery 定义如下,则可以正常工作。

testQuery = """
SELECT DISTINCT
        [sample_id]
        ,[blah]
FROM [myTableOI]
WHERE [Shipment Type] in ('test')

"""

我进行了 Google 搜索以及 Stack Overflow 中的搜索,但找不到有关特定问题的任何信息。我还查看了位于http://code.google.com/p/pymssql/wiki/FAQ 的 pymssql 文档和常见问题解答,并没有看到任何提及不允许使用临时表的内容。所以我想我会添加这个“问题”。

【问题讨论】:

【参考方案1】:

更新:2016 年 7 月

之前接受的答案不再有效。第二个“将不起作用”示例确实适用于 Python 2.7.11 下的 pymssql 2.1.1(一旦将 conn.autocommit(1) 替换为 conn.autocommit(True) 以避免“TypeError:无法将 int 转换为 bool”)。

【讨论】:

嗨@gord-thompson,感谢您的更新!我会留下我的旧答案,只是 b/c 它有更多细节,但我现在已经接受你的作为官方答案。【参考方案2】:

对于那些遇到这个问题并且可能有类似问题的人,我想我会传递我从原始帖子中学到的知识。事实证明,您可以在 pymssql 中使用临时表,但您必须非常小心处理提交的方式。

我先举例说明。以下代码将起作用:

testQuery = """
CREATE TABLE #TEST (
[name] varchar(256)
,[age] int )

INSERT INTO #TEST
values ('Mike', 12)
,('someone else', 904)

"""

conn = pymssql.connect(host=sqlServer, user=sqlID, password=sqlPwd, \
    database=sqlDB) ## obviously setting up proper variables here...
conn.autocommit(1)
cur = conn.cursor()
cur.execute(testQuery)
cur.execute("SELECT * FROM #TEST")
tmp = cur.fetchone()
tmp

这将返回第一个项目(随后的 fetch 将返回另一个):

('Mike', 12)

但以下将不起作用

testQuery = """
CREATE TABLE #TEST (
[name] varchar(256)
,[age] int )

INSERT INTO #TEST
values ('Mike', 12)
,('someone else', 904)

SELECT * FROM #TEST

"""

conn = pymssql.connect(host=sqlServer, user=sqlID, password=sqlPwd, \
    database=sqlDB) ## obviously setting up proper variables here...
conn.autocommit(1)
cur = conn.cursor()
cur.execute(testQuery)
tmp = cur.fetchone()
tmp

这将失败说“pymssql.OperationalError: No data available.”,据我所知,原因是,无论您是否启用了自动提交,以及您是否专门自己提交,所有表都必须显式创建并提交在尝试读取它们之前。

在第一种情况下,您会注意到有两个“cur.execute(...)”调用。第一个创建临时表。完成“cur.execute()”后,由于启用了自动提交,因此提交了 SQL 脚本,并制作了临时表。然后调用另一个cur.execute() 从该表中读取。在第二种情况下,我尝试“同时”创建和读取表(至少在pymssql 的脑海中......它在 MS SQL Server Management Studio 中运行良好)。由于该表之前尚未创建和提交,因此我无法对其进行查询。

哇...发现起来很麻烦,调整我的代码(最初是在 MS SQL Server Management Studio 上开发的)以使其在脚本中工作也很麻烦。哦,好吧……

【讨论】:

以上是关于pymssql(python 模块)无法使用临时表的主要内容,如果未能解决你的问题,请参考以下文章

使用 pymssql 的 Kerberos 委派(双跳)

无法使用 mod_wsgi 从 python wsgi 连接到 pymssql

为Python安装pymssql模块来连接SQLServer

Python用MySQLdb, pymssql 模块通过sshtunnel连接远程数据库

Python用MySQLdb, pymssql 模块通过sshtunnel连接远程数据库

是否可以使用 pymssql 将 python 列表写入数据库?