IronPython 堆栈跟踪引用了"except"块中的一行



我正在开发一个IronPython(v2.7.3)模块,该模块连接到远程计算机上的给定SQL Server数据库,并使用SMO为该数据库的所有对象生成脚本。 我的"真实"模块具有为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 FilesMicrosoft SQL Server100Setup BootstrapSQLServer2008R2x64'
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 行是except块中的print语句。 输出文件包含所有表的脚本、235 个 SP 的完整脚本以及第 236 个 SP 的部分脚本。 但是#236 没有什么不寻常的(无论如何我都可以看到),这应该会导致脚本失败。 我也无法理解为什么堆栈跟踪会发生,引用except块中的简单print语句。

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

因此,在这一点上,(显然)排除了SP中的问题字符或脚本过程的文件/内存大小限制,我感到困惑。

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

import codecs

然后将open呼叫替换为:

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

这对我有用。

最新更新