Получение сообщений SQL Server с использованием ADO и win32com - PullRequest
1 голос
/ 03 мая 2011

В настоящее время я пытаюсь написать инструмент, который позволит не-компьютерному пользователю создавать резервные копии базы данных SQL Server.

Для этого я надеюсь использовать интересную смесь ADOWin32com и Adodbapi.В настоящее время я могу легко подключиться к серверу и выполнить команду BACKUP DATABASE T-SQL.

Это работает, однако выполнение команды часто занимает много времени (особенно в очень больших базах данных).С этой целью я надеялся захватить и проанализировать событие InfoMessage ( MSDN ) и использовать его для отображения процентного бара / счетчика.

Это я тоже справился, теперь яЯ застрял на последнем препятствии, разбирая событие.Документы MSDN говорят, что мне нужно передать либо Ошибка , либо Ошибки в параметре 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 Ответ

0 голосов
/ 04 мая 2011

При чтении MSDN кажется, что только Error объекты должны быть переданы обработчикам событий.Если есть несколько ошибок, вы можете получить их из Errors коллекции вашего Connection объекта .Поэтому следует ожидать, что объекты Error будут переданы InfoMessage().Если вместо этого вы получаете PyIUnknown, может быть, вы можете попытаться вызвать QueryInterface() и запросить IDispatch?Вы также можете попытаться запросить конкретный пользовательский интерфейс, используемый Error, но я не помню, поддерживает ли Pythoncom пользовательские интерфейсы (т.е. не-IDispatch), и мой интернет сейчас сканирует, поэтому я не могу проверить, чтобы выЯ должен проверить это сам.В любом случае, IDispatch должен работать, несмотря ни на что, поскольку именно это использует VB6.

...