iopro.pyodbc 取消查询

从 1.5 版开始,IOPro 的 pyodbc 子模块可以取消操作。这是通过将 SQLCancel ODBC 函数公开为 Cursor 对象中的取消方法来完成的。

一个简单的例子

一个非常简单的例子是:

conn = iopro.pyodbc.connect(conn_str)
cursor = conn.cursor()
cursor.execute('SELECT something FROM sample_table')
result = cursor.fetchone()
cursor.cancel()

这不是很有趣,它并没有为 pyodbc 的功能增加太多。

使取消方法更有趣的是,可以取消阻塞另一个线程的正在运行的语句。

线程示例

可以访问取消方法,可以根据不同的标准停止运行查询。例如,可以超时执行查询。如果时间用完,查询将被取消。

import iopro.pyodbc
import time
import threading

def query_with_time_out(conn, query, timeout):
    def watchdog(cursor, time_out):
        time.sleep(wait_time)
        cursor.cancel()

    cursor = conn.cursor()

    t = threading.Thread(target=watchdog, args=(cursor, timeout))
    t.start()
    try:
        cursor.execute(query)

        result = cursor.fetchall()
    except iopro.pyodbc.Error:
        result = 'timed out'

    return result

这只是一种可能性。由于游标直接公开 SQLCancel,因此在实施取消正在运行的查询的策略时会出现许多机会。

整理笔记

为了使其工作,底层 ODBC 驱动程序必须支持 SQLCancel。

IOPro 的 pyodbc 子模块在调用 ODBC 时释放 Python GIL,因此在执行查询时,其他 Python 线程继续执行,而执行查询的线程被阻塞。这允许取消被另一个线程调用。结合线程,cancel 方法是一个非常有用的原语。