python-3.x 当通过SQL Alchemy(和Pandas)对SQL Server执行查询时,如何设置查询超时?

dzjeubhm  于 2023-06-25  发布在  Python
关注(0)|答案(1)|浏览(165)

我正在使用Python的Pandas和SQLAlchemy包来查询MS SQL Server 2019,我想设置查询的超时值,但我无法让它工作。我一直在测试一个运行15秒的SQL查询时使用三秒的查询超时。实现此行为的语法是什么?

import datetime

import pandas as pd
import sqlalchemy

connection_str = "mssql+pyodbc://@ITDEV/FACETS?trusted_connection=yes&driver=ODBC+Driver+17+for+SQL+Server"
engine = sqlalchemy.create_engine(connection_str)
with engine.begin() as conn:
    print(datetime.datetime.now())
    pd.read_sql("WAITFOR DELAY '00:00:15'; SELECT TOP 1 * FROM CMC_SBSB_SUBSC", conn)
    print(datetime.datetime.now())
yfwxisqw

yfwxisqw1#

您正在查找SQLAlchemy连接池上的连接事件处理程序,以便可以设置DBAPI连接对象的timeout属性。简而言之,它看起来像这样:

@event.listens_for(engine, "connect")
def receive_connect(dbapi_connection, connection_record):
    # This will throw:
    # pyodbc.OperationalError: ('HYT00', '[HYT00] [Microsoft][ODBC Driver 17 for SQL Server]Query timeout expired (0) (SQLExecDirectW)')
    dbapi_connection.timeout = 5
    # dbapi_connection.timeout = 20 # Succeeds

一个更完整的例子如下:

import datetime
import os
import pandas as pd
from sqlalchemy import create_engine
from sqlalchemy.engine import URL
from sqlalchemy import event

query_dict = {
    "driver": "ODBC Driver 17 for SQL Server",
    "trustServerCertificate": "yes"
}

connection_str = URL.create(
    "mssql+pyodbc",
    username = os.environ["DB_USER"],
    password = os.environ["DB_PWD"],
    host = os.environ["DB_SERVER"],
    port = 1433,
    database = "msdb",
    query = query_dict,
)

print(f"Connection String: {connection_str}");
engine = create_engine(connection_str)

@event.listens_for(engine, "connect")
def receive_connect(dbapi_connection, connection_record):
    # # This will throw:
    # # pyodbc.OperationalError: ('HYT00', '[HYT00] [Microsoft][ODBC Driver 17 for SQL Server]Query timeout expired (0) (SQLExecDirectW)')
    # dbapi_connection.timeout = 5
    dbapi_connection.timeout = 20 # Succeeds

with engine.begin() as conn:
    print(datetime.datetime.now())
    print(pd.read_sql("WAITFOR DELAY '00:00:15'; SELECT GETDATE() AS NOW", conn).to_string())
    print(datetime.datetime.now())

相关问题