В настоящее время я пытаюсь написать инструмент, который позволит пользователю, не разбирающемуся в компьютерах, очень легко создавать резервные копии базы данных SQL Server.
Для этого я надеюсь использовать интересное сочетание ADO, win32com и adodbapi. В настоящее время я могу легко подключиться к серверу и выполнить команду BACKUP DATABASE
T-SQL.
Это работает, однако выполнение команды часто занимает много времени (особенно в очень больших базах данных). С этой целью я надеялся захватить и проанализировать событие InfoMessage
(MSDN) и используйте его для отображения процентной шкалы/счетчика.
Это мне тоже удалось, теперь я застрял на последнем препятствии, разбирая событие. Документы MSDN говорят, что я должен быть передано либо Error, либо < объект href="http://msdn.microsoft.com/en-us/library/ms675299(v=vs.85).aspx" rel="nofollow noreferrer">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 и запустите резервное копирование с помощью сценария (вы можете создать сценарий, используя диалоговое окно резервного копирования и кнопку сценария в левом верхнем углу). Вы заметите, что когда вы запускаете сценарий, окно сообщений будет заполняться процентными сообщениями. Это то, что я хочу.
Редактировать:
Ниже приведен новый код, который я использую для опроса 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