Pregunta

Actualmente estoy tratando de escribir una herramienta que sea muy fácil para un usuario de alfabetización que no sea de empleo hacer una copia de seguridad de una base de datos de SQL Server.

Para hacer esto, espero usar una mezcla interesante de Ado, Win32com y ADODBAPI. Actualmente puedo conectarme fácilmente al servidor y emite un BACKUP DATABASE Comando T-SQL.

Esto funciona, sin embargo, a menudo lleva mucho tiempo el comando ejecutar (especialmente en bases de datos muy grandes). Con este fin esperaba capturar y analizar el InfoMessage evento (MSDN) y úselo para mostrar una barra/contador porcentual.

Esto también lo he logrado, ahora estoy atrapado en el obstáculo final, analizando el evento. los MSDN Los documentos dicen que debería ser aprobado cualquiera Error o Errores objeto en el pError parámetro. Sin embargo, Win32com me pasa un PyIUnknown Objeto con el que no sé cómo tratar.

A continuación se muestra el código que he escrito hasta ahora:

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'

¿Alguien puede extraer los mensajes informativos de los eventos?

Esto es implementado en VB (Pienso)

Para obtener un ejemplo de uno de estos mensajes, inicie SQL Server Management Studio y ejecute una copia de seguridad utilizando un script (puede generar el script usando el diálogo de copia de seguridad y el botón de script en la parte superior izquierda). Notará que cuando ejecute el script, el cuadro Mensajes poblará con el porcentaje de mensajes completos. Estos son lo que quiero.

Editar:

A continuación se muestra el nuevo código que estoy usando para interrogar los objetos COM que se pasan al InfoMessage. Esto se basa en la respuesta a continuación, la pongo aquí en caso de que alguien más la necesite.

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
¿Fue útil?

Solución

Leyendo msdn, solo parece Error Los objetos deben pasar a los manejadores de eventos. Si hay múltiples errores, puede obtenerlos del Errors recopilación de tu Connection objeto. Por lo tanto, solo debe esperar que los objetos de error pasen a InfoMessage(). Si obtienes pyiunknown en su lugar, tal vez puedas intentar llamar QueryInterface() ¿Sobre él y solicitar Idispatch? También puede intentar solicitar la interfaz personalizada específica Error Usos, pero no recuerdo si PythOncom admite interfaces personalizadas (es decir, no idispatch), y mi internet está gastando en este momento, por lo que no puedo verificar, por lo que tendrá que verificarlo usted mismo. De todos modos, Idispatch debería funcionar sin importar qué, ya que eso es lo que usa VB6.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top