环境:Windows 64位,python 2.7.8(32位),pyodbc v.3.0.7
对于我需要做的事情,根据内部策略,我不能使用linkedserver。
使用python,我正在尝试:
- 导出表的数据(*.dat)及其结构(格式-*.fmt)使用bcp从一个Sql Server(2008或2012)。导出的文件放在我的本地机器上。我打了两个BCP电话:一个是格式化(.fmt)文件,另一个用于获取数据的文件(.dat)(无法想办法一步到位)
- 将给定表的数据导入到数据库MyDatabase中,在那里我拥有完全权限(根据DBA的声明),并且导入到同一SQL服务器但不同的数据库上,或者完全导入到另一台服务器上。在这里,我的主要目标是自动创建要导入的表(基于导出的fmt文件)和实际导入其数据
我已经完成了第1点,在这里我可以动态地指定要导出的服务器、目录、模式和表,并且python会在我的本地机器上的一个专用文件夹DedicatedShareFolder 下自动创建table.dat和table.fmt文件
DedicatedShareFolder是我本地计算机上的一个共享文件夹,用于存储导出的表及其fmt文件。我正试图将这些表导入到的SQL Server可以访问它。
在第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 '\MyMachineNameDedicatedShareFoldertable.dat',
FORMATFILE = '\MyMachineNameDedicatedShareFoldertable.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 '\MyMachineNameDedicatedShareFoldertable.dat',
FORMATFILE = '\MyMachineNameDedicatedShareFoldertable.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 '\MyMachineNameDedicatedShareFoldertable.dat',
FORMATFILE = '\MyMachineNameDedicatedShareFoldertable.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)
跟踪文件表示表已创建。遗憾的是,事实并非如此。
出于绝望,我查看了我正在测试的服务器上的每个数据库。任何地方都没有blah表,尽管MyDatabase是我唯一拥有写权限的数据库
如果我在Microsoft SQL Server Management Studio中执行相同的"select*into…openrowset…bulk…"语句,它将成功(以python脚本中使用的相同用户身份登录)
我使用同一脚本中的函数成功地执行了许多其他与SQL相关的任务。进口是唯一不起作用的东西。
我还运行了我能想到的每一个负单元测试,以确保没有变量在中途被更改。没有什么
我是蟒蛇的初学者。我要么在代码中做了严重错误的事情,要么?
如果不能使用"select*into.openrowset etc"类型的语句来实现我的目标,我可以使用什么其他SLQ解决方案来创建表并基于其BCP dat和fmt文件加载其数据?
谢谢。
情侣选项:
使用Connection.Commit()或Cursor.Commit()提交更改。它们的功能相同,添加了
Cursor.commit()
,因此不需要来跟上Connection
对象。创建连接时,将
autocommit
变量设置为True
。请注意,它是pyodbc.connect()函数的参数,它不是连接字符串的一部分。使用您的编码风格设置autocommit
将是:。。。。cnxn=pyodbc.connect('DRIVER={SQL Server};Server=%s;DATABASE=%s;UID=%s’%(服务器、目录、登录名、密码),autocommit=True)。。。。