Domanda

Attualmente sto cercando di scrivere uno strumento che renderà molto facile per un utente alfabetizzato non computer di eseguire il backup di un database SQL Server.

Per fare questo spero di usare un interessante mix di Ado, Win32Com e Adodbapi. Attualmente posso facilmente connettermi al server e emettere a BACKUP DATABASE Comando T-SQL.

Funziona, tuttavia spesso ci vuole molto tempo per l'esecuzione del comando (specialmente su database molto grandi). A tal fine speravo di catturare e analizzare il InfoMessage evento (Msdn) e usalo per mostrare una barra/contatore percentuale.

Anche questo sono riuscito, ora sono bloccato all'ostacolo finale, analizzando l'evento. Il Msdn I dottori dicono che dovrei essere superato uno Errore o Errori oggetto nel pError parametro. Tuttavia Win32Com mi passa a PyIUnknown oggetto che non so come affrontare.

Di seguito è riportato il codice che ho scritto finora:

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'

Qualcuno può estrarre i messaggi informativi dagli eventi?

Questo è implementato in VB (Penso)

Per un esempio di uno di questi messaggi avviare SQL Server Management Studio ed eseguire un backup utilizzando uno script (è possibile generare lo script utilizzando il dialogo di backup e il pulsante di script in alto a sinistra). Noterai che quando si esegue lo script, la casella dei messaggi popolerà con messaggi completi percentuali. Questi sono quello che voglio.

Modificare:

Di seguito è riportato il nuovo codice che sto usando per interrogare gli oggetti COM che vengono passati al InfoMessage. Questo si basa sulla risposta qui sotto, lo metto qui nel caso in cui qualcun altro ne abbia bisogno.

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
È stato utile?

Soluzione

Leggendo MSDN, sembra solo Error Gli oggetti dovrebbero essere passati ai gestori dell'evento. Se ci sono più errori, puoi ottenerli da Errors collezione del tuo Connection oggetto. Quindi dovresti aspettarti solo che gli oggetti di errore vengano passati InfoMessage(). Se invece si ottiene Pyiunknown, forse puoi provare a chiamare QueryInterface() su di esso e richiedi Idispatch? Puoi anche provare a richiedere l'interfaccia personalizzata specifica Error Usi, ma non ricordo se Pythoncom supporta interfacce personalizzate (cioè non idispatch) e la mia Internet sta strisciando in questo momento, quindi non posso controllare, quindi dovrai controllarlo da solo. Ad ogni modo, IdisPatch dovrebbe funzionare, non importa quale, dato che è ciò che VB6 usa.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top