我正在开发一个IronPython(v2.7.3)模块,该模块连接到远程计算机上的给定SQL Server数据库,并使用SMO为该数据库的所有对象生成脚本。 我的"真实"模块具有为SMO中每个定义的对象类型生成脚本的代码,从ApplicationRoles
到XmlSchemaCollections
。 我正在使用的数据库在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')
这对我有用。