在SQL Server上使用pyodbc时,在openrowset(BULK..)的表中使用select*创建表无效



环境:Windows 64位,python 2.7.8(32位),pyodbc v.3.0.7

对于我需要做的事情,根据内部策略,我不能使用linkedserver。

使用python,我正在尝试:

  1. 导出表的数据(*.dat)及其结构(格式-*.fmt)使用bcp从一个Sql Server(2008或2012)。导出的文件放在我的本地机器上。我打了两个BCP电话:一个是格式化(.fmt)文件,另一个用于获取数据的文件(.dat)(无法想办法一步到位)
  2. 将给定表的数据导入到数据库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对象中禁用事务的自动提交。您请求的所有工作实际上都已完成,事务只是在连接关闭时回滚。

情侣选项:

  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’%(服务器、目录、登录名、密码),autocommit=True)。。。。

相关内容

  • 没有找到相关文章

最新更新