環境:64位的Windows,蟒蛇2.7.8(32位),pyodbc v 3.0.7在SQL Server上的pyodbc,創建表使用select *成從OPENROWSET表(BULK ...)沒有任何影響
對於我需要做的事情,我無法根據內部策略使用鏈接服務器。
使用Python,我試圖:
- 導出表數據(* .dat文件)及其結構 - 從一個SQL服務器(無論是2008年或2012年)(格式爲*的.fmt) 使用BCP。導出的 文件位於本地計算機上。我做了2個BCP調用:一個獲得 格式(.fmt)文件,另一個獲取數據(.dat)(不能 找到一種方法可以一步完成)
- 導入給定表的數據到數據庫 - 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文件加載其數據?
謝謝。