2012-01-09 79 views
0

這不是一個問題,而是一個先發制人的答案。 (我從這個網站得到了很多幫助&想要回報。)pymssql(python模塊)無法使用臨時表

我一直在努力與大量的SQL查詢失敗,當我試圖通過python使用pymssql運行它,但會運行良好時直接通過MS SQL。 (例如,在我的情況下,我使用MS SQL Server Management Studio在python之外運行它。)

然後我終於發現問題:pymssql無法處理臨時表。至少不是我的版本,它仍然是1.0.1。

爲了證明這一點,這裏是我的代碼片段,稍微改變,以保護任何知識產權問題:

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

上面的代碼失敗(沒有返回數據,具體而言,和吐錯誤「pymssql.OperationalError: No data available.」如果調用cur.fetchone())如果我有如下定義testQuery稱之爲:

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') 

""" 

我做了谷歌搜索以及堆棧溢出內進行搜索,也找不到關於特定問題的任何信息。我還查看了在http://code.google.com/p/pymssql/wiki/FAQ找到的pymssql文檔和常見問題解答,並沒有看到任何提及臨時表不被允許的內容。所以我想我會添加這個「問題」。

回答

2

更新:2016年7月

先前接受的答案不再有效。第二個「不起作用」的例子確實可以在Python 2.7.11下使用pymssql 2.1.1(一旦conn.autocommit(1)被替換爲conn.autocommit(True)以避免「TypeError:無法將int轉換爲bool」)。

+1

嗨@ gord-thompson,感謝您的更新!我會留下我原來的答案,只是說它有更多的細節,但我現在已經接受你的答案。 – 2016-07-27 16:24:48

1

對於那些遇到這個問題並且可能有類似問題的人,我想我會傳遞自從原始帖子後學到的東西。事實證明,您可以在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 

這將然後返回的第一個項目(後續的獲取將返回其他):

('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.」原因,盡我所知,無論你是否有自動提交,並且你是否自己專門提交一個提交,所有表必須expli在嘗試讀取它們之前,應該創建並提交。

在第一種情況下,您會注意到有兩個「cur.execute(...)」調用。第一個創建臨時表。在完成「cur.execute()」後,由於自動提交功能處於打開狀態,SQL腳本被提交,臨時表被創建。然後調用另一個cur.execute()從該表中讀取。在第二種情況下,我試圖創建&「同時」從表中讀取(至少在pymssql的意義上......它在MS SQL Server Management Studio中正常工作)。由於該表以前未提交過,所以我無法查詢它。

哇...這是一件很難發現的事情,調整我的代碼(首先在MS SQL Server Management Studio上開發)以便它能夠在腳本中工作將會是一件麻煩事。哦...