Получение сообщений 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.

Другие вопросы по тегам