Получение сообщений SQL Server с использованием ADO и win32com
В настоящее время я пытаюсь написать инструмент, который позволит не-компьютерному пользователю легко создавать резервные копии базы данных SQL Server.
Для этого я надеюсь использовать интересную смесь ADO, win32com и adodbapi. В настоящее время я могу легко подключиться к серверу и выдает BACKUP DATABASE
Команда T-SQL.
Это работает, однако для выполнения команды часто требуется много времени (особенно в очень больших базах данных). С этой целью я надеялся захватить и разобрать InfoMessage
событие ( MSDN) и использовать его для отображения процентного бара / счетчика.
С этим я тоже справился, теперь я застрял на последнем препятствии, разбирая событие. Документы MSDN говорят, что мне нужно передать объект Error или 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
1 ответ
Чтение MSDN, кажется, только Error
объекты должны быть переданы обработчикам событий. Если есть несколько ошибок, вы можете получить их из Errors
коллекция вашего Connection
объект. Поэтому следует ожидать, что объекты Error будут переданы InfoMessage()
, Если вместо этого вы получаете PyIUnknown, возможно, вы можете попробовать позвонить QueryInterface()
на это и запросить IDispatch? Вы также можете попробовать запросить специальный пользовательский интерфейс Error
использует, но я не помню, поддерживает ли Pythoncom пользовательские (то есть не-IDispatch) интерфейсы, и мой интернет сканирует прямо сейчас, поэтому я не могу проверить, поэтому вам придется проверить это самостоятельно. В любом случае, IDispatch должен работать несмотря ни на что, поскольку именно это использует VB6.