0

我目前正在尝试在运行命令InfoMessage时从 ADO(和 SQL 服务器)获取事件返回的百分比完成消息。(有关详细信息,BACKUP请参阅我之前的问题)。

我已经设法连接到 SQL 服务器并发出 SQL 命令,然后事件获取事件。但是,当我执行BACKUP命令时,cmd.Execute方法会阻塞,直到备份完成。

但在此期间,我将收到一个事件 InfoMessage调用(其中会显示“1% 完成”之类的消息),之后我将不再收到任何事件。

我已经尝试过使用存储过程,其中存储过程打印 3 条消息,即使在这里我也会得到第一条消息,没有别的。

我怀疑我需要 call pythoncom.PumpWaitingMessages(),但因为cmd.Execute()call 阻塞了我从来没有得到任何有用的东西。

任何人都可以计算出如何获得更多,而不仅仅是一个InfoMessage事件。

以下是我目前正在使用的代码:

import win32com
import pythoncom
import adodbapi
import time
import win32gui
from win32com.client import gencache
gencache.EnsureModule('{2A75196C-D9EB-4129-B803-931327F72D5C}', 0, 2, 8)

defaultNamedOptArg=pythoncom.Empty
defaultNamedNotOptArg=pythoncom.Empty
defaultUnnamedArg=pythoncom.Empty

global connected
connected = False

class events():
    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
        return 1

    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):
        print 'Execute Event'
        return Source
    def OnDisconnect(self, adStatus=defaultNamedNotOptArg, pConnection=defaultNamedNotOptArg): 
        print 'Disconnected'
    def OnExecuteComplete(self, RecordsAffected=defaultNamedNotOptArg, pError=defaultNamedNotOptArg, adStatus=defaultNamedNotOptArg, pCommand=defaultNamedNotOptArg
            , pRecordset=defaultNamedNotOptArg, pConnection=defaultNamedNotOptArg):
        print 'Execute complete'
    def OnWillConnect(self, ConnectionString=defaultNamedNotOptArg, UserID=defaultNamedNotOptArg, Password=defaultNamedNotOptArg, Options=defaultNamedNotOptArg
            , adStatus=defaultNamedNotOptArg, pConnection=defaultNamedNotOptArg):
        print 'About to connect'
    def OnConnectComplete(self, pError=defaultNamedNotOptArg, adStatus=defaultNamedNotOptArg, pConnection=defaultNamedNotOptArg):
        print 'Connected'
        global connected
        connected = True
    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)

    conn.ConnectionString = 'Data Source=HPDX2250RAAZ\\SQLEXPRESS; Provider=SQLOLEDB; Integrated Security=SSPI'
    conn.CommandTimeout = 30
    conn.CursorLocation = 2
    conn.Open(pythoncom.Empty,pythoncom.Empty,pythoncom.Empty,0x10)

    while not connected:
        #pythoncom.PumpWaitingMessages()
        win32gui.PumpWaitingMessages()
        time.sleep(0.1)

    conn.BeginTrans()
    conn.Errors.Clear()
    cmd=win32com.client.Dispatch("ADODB.Command")
    cmd.ActiveConnection=conn
    cmd.CommandTimeout = 30  #v2.1 Simons
    cmd.CommandText="EXECUTE [test].[dbo].[Test] "
    print 'Execute'
    cmd.Execute()

    pythoncom.PumpWaitingMessages()
    print 'Called'
    print ''
    print conn.Errors.Count
    conn.RollbackTrans()
    conn.Close()
4

2 回答 2

1

我遇到了同样的问题,问题是什么,如果您遇到同样的问题,消息基本上是由 SQL Server 引擎本身阻止的。为了解决这个问题,您需要告诉 SQL 不要等到处理结束才发送消息,而是在它们发生时发送它们。试穿这个尺寸:

SET @message = 'My message...'
RAISERROR (@message, 10, 1) WITH NOWAIT

这应该会发送消息,并且您的前端应该会随着系统的运行而接收这些消息。

希望这可以帮助

于 2011-06-30T17:39:55.663 回答
0

我找到了一种与 pymssql 和其他驱动程序兼容的解决方法。我使用 SQL 中的 SQL是否有可用于确定 SQL Server 备份或还原过程的进度的 SQL 脚本?加上每 X 秒运行该查询的后台线程。现在,为了通知,我使用http://pydispatcher.sourceforge.net/来取回进度。

#This is rough extract from my actual code. Probably not work as is, but outline the idea
import dispatch #Decoupled send of messages, identical to django signals

def monitorBackup(self):
    return self.selectSql(SQL_MONITOR)

def backup(sql):
    con = self.getCon() #Get new connection, we are in another thread!
    con.execute_query("HERE THE BACKUP SQL")

result = threading.Thread(target=partial(backup, sql))

result.start()

while result.isAlive():
    time.sleep(5) # with the monitor SQL result, is possible to get a estimated time to complete and adjust this...
    rows = self.monitorBackup()

    if len(rows) > 0:
        percentage = rows[0].Percent

        self.send(
            msg="%d %%" % percentage,
            action="progress",
            progress=percentage
        )
于 2012-12-20T23:58:47.403 回答