2

環境:64位的Windows,蟒蛇2.7.8(32位),pyodbc v 3.0.7在SQL Server上的pyodbc,創建表使用select *成從OPENROWSET表(BULK ...)沒有任何影響

對於我需要做的事情,我無法根據內部策略使用鏈接服務器。

使用Python,我試圖:

  1. 導出表數據(* .dat文件)及其結構 - 從一個SQL服務器(無論是2008年或2012年)(格式爲*的.fmt) 使用BCP。導出的 文件位於本地計算機上。我做了2個BCP調用:一個獲得 格式(.fmt)文件,另一個獲取數據(.dat)(不能 找到一種方法可以一步完成)
  2. 導入給定表的數據到數據庫 - MyDatabase - 我擁有完全權限(根據DBA的聲明),並且在同一個SQL服務器上,但在不同的數據庫上,或者在另一個服務器上。在這裏,我的主要目標是自動創建要導入的表(基於導出的fmt文件)以及實際導入其數據。

我有點1工作,在那裏我可以動態地指定要導出的服務器,目錄,模式和表,並且python會自動在我的本地機器上創建table.dat和table.fmt文件。專用文件夾 - DedicatedShareFolder

DedicatedShareFolder是我本地機器上的一個共享文件夾,用於存儲導出的表格及其fmt文件。我試圖將這些表導入到的SQL服務器可以訪問它。

在第2點,我用Python來構建一個SQL語句如下:

sql = "select * into %s from 
openrowset(BULK '\\\\%s\\sqltemp\\%s.dat', 
FORMATFILE = '\\\\%s\\sqltemp\%s.fmt') as A" %(newTableName,os.environ['COMPUTERNAME'], 
table,os.environ['COMPUTERNAME'],table) 

這最終看起來像:

select A.* into MyDatabase.dbo.blah48 from 
openrowset(BULK '\\MyMachineName\DedicatedShareFolder\table.dat', 
FORMATFILE = '\\MyMachineName\DedicatedShareFolder\table.fmt') as A; 

我創建到具有MyDatabase的SQL服務器的連接,並執行:

cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=%s;DATABASE=%s;UID=%s;PWD=%s' % (server, catalog, login, pw)) 
cursor = cnxn.cursor() 
rows = cursor.execute(sql).rowcount 
print "Done importing %s rows" %rows 

我得到:

Done importing 606597 rows 

可惜的是,該表沒有創建

我跑使用「ODBC數據源管理」的「跟蹤」選項卡我的本地機器上的痕跡。我打開了日誌文件,並且找不到與創建表有關的任何錯誤。我看到的條目是這樣的:

test_DB 5200-5a28 EXIT SQLDriverConnectW with return code 1 (SQL_SUCCESS_WITH_INFO) 
     HDBC    0x03C59190 
     HWND    0x00000000 
     WCHAR *    0x74C28B34 [  -3] "******\ 0" 
     SWORD      -3 
     WCHAR *    0x74C28B34 <Invalid buffer length!> [-3] 
     SWORD      -3 
     SWORD *    0x00000000 
     UWORD      0 <SQL_DRIVER_NOPROMPT> 

     DIAG [01000] [Microsoft][ODBC SQL Server Driver][SQL Server]Changed database context to 'mydatabase'. (5701) 

     DIAG [01000] [Microsoft][ODBC SQL Server Driver][SQL Server]Changed language setting to us_english. (5703) 

     DIAG [01S00] [Microsoft][ODBC SQL Server Driver]Invalid connection string attribute (0) 

我懷疑「無效的緩衝區長度」在這裏有沒有影響(無法找到我的搜索它的信息),和我看到司機不斷變化的環境和語言的成功。

我也看到在跟蹤日誌條目數是這樣的:

test_DB 50c0-4fec EXIT SQLGetTypeInfo with return code -1 (SQL_ERROR) 
     HSTMT    0x03AC8E80 
     SWORD      12 <SQL_VARCHAR> 

     DIAG [24000] [Microsoft][ODBC Driver Manager] Invalid cursor state (0) 

沒有顯著在我的搜索,它表明「無效的光標狀態」在這裏有任何影響橫空出世。以上條目可能是由於我還在努力的其他代碼部分。

進一步下跌的跟蹤日誌,我看到:

test_DB 50c0-4fec ENTER SQLExecDirect 
     HSTMT    0x03ACB5B0 
     UCHAR *    0x025BBB94 [  -3] "select A.* into MyDatabase.dbo.blah48 from 
openrowset(BULK '\\MyMachineName\DedicatedShareFolder\table.dat', 
FORMATFILE = '\\MyMachineName\DedicatedShareFolder\table.fmt') as A\ 0" 
     SDWORD     -3 

test_DB 50c0-4fec EXIT SQLExecDirect with return code 0 (SQL_SUCCESS) 
     HSTMT    0x03ACB5B0 
     UCHAR *    0x025BBB94 [  -3] "select A.* into MyDatabase.dbo.blah48 from 
openrowset(BULK '\\MyMachineName\DedicatedShareFolder\table.dat', 
FORMATFILE = '\\MyMachineName\DedicatedShareFolder\table.fmt') as A\ 0" 
     SDWORD     -3 

test_DB 50c0-4fec ENTER SQLRowCount 
     HSTMT    0x03ACB5B0 
     SQLLEN *   0x0027EFD4 

test_DB 50c0-4fec EXIT SQLRowCount with return code 0 (SQL_SUCCESS) 
     HSTMT    0x03ACB5B0 
     SQLLEN *   0x0027EFD4 (606597) 

跟蹤文件指示表已創建。唉,它不是。

出於絕望,我查看了我測試的服務器上的每個數據庫。即使MyDatabase是我擁有的唯一寫權限

如果我在Microsoft SQL Server Management Studio中執行相同的「select * into ... openrowset ... bulk ...」語句,它成功(以python腳本中使用的相同用戶身份登錄)

我使用同一腳本中的函數成功執行許多其他SQL相關任務。導入是唯一不起作用的東西。

我也跑了每一個負面的單元測試,我可以想到確保沒有變量中途得到改變。沒有。

我是一個Python初學者。我要麼在我的代碼中嚴重錯誤,要麼?

如果「select * into .. openrowset etc」類型的語句不能用於實現我的目標,我可以使用其他SLQ解決方案創建表並根據其BCP dat和fmt文件加載其數據?

謝謝。

回答

0

默認情況下,在Connection對象中禁用了事務的自動落實。您所要求的所有工作實際上都已完成,只有在連接關閉時纔會回滾事務。

夫婦選擇:

  1. 與任Connection.commit()Cursor.commit()提交更改。它們在功能上是相同的,因此增加了Cursor.commit()因此它不是必需以跟上Connection對象。

  2. 創建連接時,將autocommit變量設置爲True。請注意,它是pyodbc.connect()函數的參數,它不是連接字符串的一部分。與你的編碼風格設置autocommit將是:

    .... 
    cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=%s;DATABASE=%s;UID=%s;PWD=%s' % (server, catalog, login, pw), 
             autocommit=True) 
    .... 
    
相關問題