IronPython堆栈跟踪引用“except”块中的一行

时间:2013-09-17 08:07:34

标签: sql-server ironpython smo

我正在开发一个IronPython(v2.7.3)模块,该模块连接到远程计算机上的给定SQL Server数据库,并使用SMO为所有该DB的对象生成脚本。我的“真实”模块具有为SMO中的每个已定义对象类型生成脚本的代码,从ApplicationRolesXmlSchemaCollections。我正在使用的数据库是在SQL Server 2000上。它有相当数量的对象 - 117个表,257个SP,101个视图等。

每次运行模块时,我都会在编写SP脚本的位置获得堆栈跟踪。我减少了模块以仅编写表和SP的脚本,并且在编写SP脚本时仍然失败。这是精简版:

import sys, clr
import System.Array

serverName     = r'x.x.x.x' #IP address of remote server
pathAssemblies = r'C:\Program Files\Microsoft SQL Server\100\Setup Bootstrap\SQLServer2008R2\x64'
sys.path.append(pathAssemblies)
clr.AddReferenceToFile('Microsoft.SqlServer.Smo.dll')
import Microsoft.SqlServer.Management.Smo as SMO

srv  = SMO.Server(serverName)
srv.ConnectionContext.LoginSecure = False
srv.ConnectionContext.Login = 'sa'
srv.ConnectionContext.Password = 'foo' #Password of sa
db = srv.Databases['bar']  #Name of database
scrp = SMO.Scripter(srv)

sys.stdout = open('DBScriptOutput.txt', 'w')

try:
    for dbgenobj in db.Tables:
       urns = System.Array[SMO.SqlSmoObject]([dbgenobj])
       outStr = scrp.Script(urns)
       for outLine in outStr:print outLine
except:
    print 'Failed out while generating table scripts.'

try:
    for dbgenobj in db.StoredProcedures:
       urns = System.Array[SMO.SqlSmoObject]([dbgenobj])
       outStr = scrp.Script(urns)
       for outLine in outStr:print outLine
except:
    print 'Failed out while generating stored procedure scripts.'

让我难过的难题涉及两件似乎没有意义的事情:

(1)堆栈轨道本身如下所示:

Traceback (most recent call last):
  File "E:\t.py", line 33, in <module>
UnicodeEncodeError: ('unknown', '\x00', 0, 1, '')

第33行是print块中的except语句。输出文件包含所有表的脚本,235个SP的完整脚本以及第236个脚本的部分脚本。但是对于#236而言,没有什么不寻常的(我可以看到),这会导致脚本失败。我也无法理解为什么堆栈跟踪会引用print块中的简单except语句。

(2)作为进一步的故障排除实验,我尝试使用整个try-except块运行脚本,以便对表进行注释。它仍然无法生成SP脚本,并生成相同的堆栈跟踪引用第33行。不同之处在于它在终止之前成功为过程#236生成另外16行脚本。但是输出文件的整体文件大小要小得多。我可以理解文件是否以相同的大小停止,或者脚本停止在SP中的同一点,但这些都不是真的。

所以在这一点上,(显然)已经排除了SP中的问题字符或脚本编写过程的文件/内存大小限制,我很难过。

1 个答案:

答案 0 :(得分:1)

我在注释中包含非ASCII字符的过程中遇到此问题。最简单的解决方案是使用编解码器模块和codecs.open而不是普通open调用。将其添加到导入行:

import codecs

然后将open调用替换为:

sys.stdout = codecs.open('DBScriptOutput.txt', 'w', 'utf8')

这对我有用。