我目前正在尝试编写一个工具,使不懂计算机的用户可以轻松备份 SQL Server 数据库。
为此,我希望使用 ADO、win32com 和 adodbapi 的有趣组合。目前我可以轻松连接到服务器并发出BACKUP DATABASE
T-SQL 命令。
这是可行的,但是命令的执行通常需要很长时间(尤其是在非常大的数据库上)。为此,我希望捕获并解析InfoMessage
event (MSDN)并用它来显示百分比条/计数器。
我也做到了这一点,现在我陷入了最后的障碍,解析事件。这MSDN文档说我应该通过Error or Errors对象在pError
范围。然而 win32com 给了我一个PyIUnknown
我不知道如何处理的对象。
下面是我迄今为止编写的代码:
import win32com
import pythoncom
import adodbapi
from win32com.client import gencache
gencache.EnsureModule('{2A75196C-D9EB-4129-B803-931327F72D5C}', 0, 2, 8)
defaultNamedOptArg=pythoncom.Empty
defaultNamedNotOptArg=pythoncom.Empty
defaultUnnamedArg=pythoncom.Empty
class events():
def OnInfoMessage(self, pError, adStatus, pConnection):
print 'A', pError
#print 'B', adStatus
#print 'C', pConnection
# This is taken from the makepy file
# def OnCommitTransComplete(self, pError=defaultNamedNotOptArg, adStatus=defaultNamedNotOptArg, pConnection=defaultNamedNotOptArg): pass
def OnWillExecute(self, Source=defaultNamedNotOptArg, CursorType=defaultNamedNotOptArg, LockType=defaultNamedNotOptArg, Options=defaultNamedNotOptArg
, adStatus=defaultNamedNotOptArg, pCommand=defaultNamedNotOptArg, pRecordset=defaultNamedNotOptArg, pConnection=defaultNamedNotOptArg):
return Source
# def OnDisconnect(self, adStatus=defaultNamedNotOptArg, pConnection=defaultNamedNotOptArg): pass
def OnExecuteComplete(self, RecordsAffected=defaultNamedNotOptArg, pError=defaultNamedNotOptArg, adStatus=defaultNamedNotOptArg, pCommand=defaultNamedNotOptArg
, pRecordset=defaultNamedNotOptArg, pConnection=defaultNamedNotOptArg): pass
#print pError
def OnWillConnect(self, ConnectionString=defaultNamedNotOptArg, UserID=defaultNamedNotOptArg, Password=defaultNamedNotOptArg, Options=defaultNamedNotOptArg
, adStatus=defaultNamedNotOptArg, pConnection=defaultNamedNotOptArg): pass
# def OnConnectComplete(self, pError=defaultNamedNotOptArg, adStatus=defaultNamedNotOptArg, pConnection=defaultNamedNotOptArg): pass
# def OnBeginTransComplete(self, TransactionLevel=defaultNamedNotOptArg, pError=defaultNamedNotOptArg, adStatus=defaultNamedNotOptArg, pConnection=defaultNamedNotOptArg):pass
# def OnRollbackTransComplete(self, pError=defaultNamedNotOptArg, adStatus=defaultNamedNotOptArg, pConnection=defaultNamedNotOptArg): pass
if __name__ == '__main__':
pythoncom.CoInitialize()
conn = win32com.client.DispatchWithEvents("ADODB.Connection", events)
print dir(conn)
conn.ConnectionString = 'Initial Catalog=test; Data Source=HPDX2250RAAZ\\SQLEXPRESS; Provider=SQLOLEDB.1; Integrated Security=SSPI'
conn.CommandTimeout = 30
print conn.ConnectionString
conn.Open()
con = adodbapi.Connection(conn)
c = con.cursor()
import time
print 'Execute'
time.sleep(1)
c.execute(u"BACKUP DATABASE [test] TO DISK = N'c:/test/test2' WITH STATS = 1")
print 'Done Execute'
任何人都可以从事件中提取信息性消息吗?
这是它的实现VB(我认为)
有关其中一条消息的示例,请启动 SQL Server Management Studio 并使用脚本运行备份(您可以使用备份对话框和左上角的脚本按钮生成脚本)。您会注意到,运行脚本时,消息框将填充完成消息的百分比。这些就是我想要的。
Edit:
下面是我用来询问传递给 COM 对象的新代码InfoMessage
。这是基于下面的答案,我将其放在这里以防其他人需要它。
def OnInfoMessage(self, pError, adStatus, pConnection):
print 'Info Message'
a = pError.QueryInterface(pythoncom.IID_IDispatch)
a = win32com.client.Dispatch(a)
print a.Description
print a.Number
print a.Source
#print 'B', adStatus
c = pConnection.QueryInterface(pythoncom.IID_IDispatch)
c = win32com.client.Dispatch(c)
print c.Errors.Count
print c.Errors.Item(0).Description
print c.Errors.Clear()
print 'c', adStatus