Вопрос

I'm working on an IronPython (v2.7.3) module that connects to a given SQL Server database on a remote machine, and uses SMO to generate scripts for all of that DB's objects. My 'real' module has the code to generate a script for every defined object type in SMO, from ApplicationRoles to XmlSchemaCollections. The DB I'm working with is on SQL Server 2000. It has a fair number of objects -- 117 tables, 257 SPs, 101 views, etc.

Every time I run my module, I get a stack trace at the point where it's scripting the SPs. I trimmed down to module to script only the tables and the SPs, and it still failed out while scripting the SPs. Here's the trimmed-down version:

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.'

The puzzle here that has me stumped involves two things that don't seem to make sense:

(1) The stack track itself looks like this:

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

Line 33 though is the print statement in the except block. The output file has all of the tables' scripts, complete scripts for 235 of the SPs, and part of the script for the 236th. But there's nothing unusual (that I can see anyway) about #236 that should cause the scripting to fail out. Nor can I understand why the stack trace would occur at all citing a simple print statement in the except block.

(2) As a further troubleshooting experiment, I tried running the script with the whole try-except block for the tables commented out. It still fails generating the SP scripts, and generates the same stack trace citing line 33. The difference is this time it successfully generates another 16 lines of the script for procedure #236 before terminating. The overall file size of the output file is significantly smaller though. I could understand if the file stopped at the same size, or if the scripting stopped at the same point in the SP, but neither one of these is true.

So at this point, having (apparently) ruled out a problem character in the SP or a file/memory size limit for the scripting process, I'm stumped.

Это было полезно?

Решение

I've got this problem with procedure that had non-ASCII characters in comments. The simplest solution is to use the codecs module and codecs.open instead of plain open call. Add this to the import lines:

import codecs

then replace open call with:

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

That worked for me.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top