Question

J'essaie actuellement d'écrire un outil qui permettra à un utilisateur non averti en informatique de sauvegarder une base de données SQL Server très facilement.

Pour ce faire, j'espère utiliser un mélange intéressant d'ADO, de win32com et d'adodbapi. Actuellement, je peux facilement me connecter au serveur et émettre une commande BACKUP DATABASE T-SQL.

Cela fonctionne, mais l'exécution de la commande prend souvent beaucoup de temps (surtout sur de très grandes bases de données). À cette fin, j'espérais capturer et analyser l'événement InfoMessage ( MSDN ) et utilisez-le pour afficher une barre / compteur de pourcentage.

Cela, j'ai également réussi, je suis maintenant coincé au dernier obstacle, l'analyse de l'événement. La documentation MSDN dit que je devrais être transmis soit une Erreur soit < un objet href="http://msdn.microsoft.com/en-us/library/ms675299(v=vs.85).aspx" rel="nofollow noreferrer"> Erreurs dans le paramètre pError. Cependant win32com me passe un objet PyIUnknown que je ne sais pas comment gérer.

Voici le code que j'ai écrit jusqu'à présent:

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'

Quelqu'un peut-il extraire les messages d'information des événements?

Ceci est implémenté dans VB (je pense )

Pour un exemple de l'un de ces messages, démarrez SQL Server Management Studio et exécutez une sauvegarde à l'aide d'un script (vous pouvez générer le script à l'aide de la boîte de dialogue de sauvegarde et du bouton de script en haut à gauche). Vous remarquerez que lorsque vous exécutez le script, la boîte de messages se remplit de messages en pourcentage achevé. Voilà ce que je veux.

Modifier:

Vous trouverez ci-dessous le nouveau code que j'utilise pour interroger les objets COM qui sont passés au InfoMessage. Ceci est basé sur la réponse ci-dessous, je la mets ici au cas où quelqu'un d'autre en aurait besoin.

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
Était-ce utile?

La solution

En lisant MSDN, il semble que seuls les objets Error devraient être passés aux gestionnaires d'événements.S'il y a plusieurs erreurs, vous pouvez les récupérer à partir de la collection Errors de votre objet Connection .Vous ne devez donc vous attendre à ce que les objets Error soient transmis à InfoMessage().Si vous obtenez PyIUnknown à la place, vous pouvez peut-être essayer d'appeler QueryInterface() dessus et demander IDispatch?Vous pouvez également essayer de demander l'interface personnalisée spécifique utilisée par Error, mais je ne me souviens pas si Pythoncom prend en charge les interfaces personnalisées (c'est-à-dire non IDispatch), et mon Internet est en train d'explorer en ce moment, je ne peux donc pas vérifier, vous devrezvérifiez cela vous-même.Quoi qu'il en soit, IDispatch devrait fonctionner quoi qu'il arrive, puisque c'est ce que VB6 utilise.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top