Получение сообщений SQL Server с использованием ADO и win32com

1

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

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

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

Это я тоже справился, теперь я застрял в последнем препятствии, разобрав событие. MSDN docs говорят, что мне нужно передать либо Error или Ошибки в параметре 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 и запустите резервную копию с помощью script (вы можете сгенерировать script с помощью диалога резервного копирования и кнопки script в верхнем левом углу). Вы заметите, что при запуске script в поле сообщений будут заполняться процентные сообщения. Это то, что я хочу.

Изменить:

Ниже приведен новый код, который я использую для опроса 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
Теги:
sql-server
win32com
ado
adodbapi

1 ответ

0
Лучший ответ

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

  • 0
    Запрашивая интерфейс IDispatch , а затем передавая его в win32com.client.Dispatch() получаете объект COM с поздней привязкой, который позволяет мне получить доступ к нужным мне данным. Однако я получаю только один вызов InfoMessage с объектом Error.
  • 0
    Как сказано в документации, если есть более одной ошибки, вы можете получить все ошибки из Connection.Errors . Я не уверен, как это поможет вам отслеживать прогресс, хотя.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню