HOWTO · Python

使用 Python 和 Pyodbc 连接到 Microsoft SQL Server

了解如何使用 Python 和 pyodbc 连接到 Microsoft SQL Server

本页内容

使用 pyodbc 通过 ODBC 将 Python 应用连接到 Microsoft SQL Server。安装 Python 套件和兼容的 SQL Server ODBC 驱动程序,然后将服务器、数据库、驱动程序和身份验证设置传给 pyodbc.connect()。本指南使用直接 SQL;如果希望将数据库表表示为 Python 对象,也可以选择 ORM。

安装 pyodbc 和 SQL Server ODBC 驱动程序

将 pyodbc 安装到运行应用程序的同一个 Python 环境中,例如使用 python -m pip install pyodbc。这会安装 Python 接口,但不会安装 Microsoft 的 ODBC 驱动程序。请在程序运行所在的计算机或容器上另行安装 SQL Server ODBC 驱动程序,并确认驱动程序名称与已安装的名称完全一致。常见的驱动程序名称是 ODBC Driver 18 for SQL Server;请使用系统上实际可用的名称。

连接前,请准备服务器地址和数据库名称。服务器可以是主机名、地址,或主机名加实例名,例如 db.example.net\SQLEXPRESS;托管环境也可能需要端口。管理员可能还需要授予该账户访问所选数据库的权限。SQL Server 连接信息与 Python 的工作目录无关,但操作系统的 ODBC 管理器必须能够找到该驱动程序。

使用驱动程序和受信任的身份验证进行连接

在已配置集成身份验证的 Windows 环境中,请使用包含 Trusted_Connection=yes 的驱动程序连接字符串。将驱动程序、服务器和数据库的值替换为你安装环境中的实际值。下面的简短程序会构建并显示连接字符串,方便你确认各字段如何组合;它不会连接数据库。

运行此示例:

本节中的代码以及显示的标签或输出仍为英文。

driver = "ODBC Driver 18 for SQL Server"
server = "db.example.net"
database = "Sales"
connection_string = (
    f"Driver={{{driver}}};"
    f"Server={server};"
    f"Database={database};"
    "Trusted_Connection=yes;"
)
print(connection_string)
Driver={ODBC Driver 18 for SQL Server};Server=db.example.net;Database=Sales;Trusted_Connection=yes;

在应用程序中打开连接时,将该字符串传给 pyodbc.connect(connection_string)。集成身份验证使用当前进程可用的身份,并取决于操作系统、驱动程序和 SQL Server 配置;它不同于提供 SQL Server 用户名和密码。TLS 配置应遵循组织的证书策略。不同版本的驱动程序可能采用不同的加密默认值,因此不要仅为了让连接成功就关闭证书检查。

通过 DSN 和凭据进行连接

数据源名称(DSN)是在主机上创建的 ODBC 配置。它可以保存共享的服务器和驱动程序设置,让应用程序只需提供 DSN 名称,并在需要时提供凭据。连接字符串的形式为 DSN=SalesReadOnly;UID=app_reader;PWD=<secret>;。DSN 必须存在于同一环境中,并且 Python 进程必须能够访问它;为交互式用户配置的 DSN,服务账户或容器可能无法使用。

请通过密钥管理器或特定环境的配置提供凭据,不要将凭据提交到源代码管理中。如果密钥包含特殊字符,请遵循 ODBC 连接字符串所支持的引号规则,或单独配置凭据;否则,分号可能会被解释为字段分隔符。不要打印完整的连接字符串,以免密码出现在日志中。使用 DSN 字符串调用同一个 pyodbc.connect(...),并根据 DSN 和服务器的配置选择集成身份验证或 SQL 身份验证。

执行查询并关闭资源

连接成功后,创建游标、执行 SQL,然后读取或迭代返回的行。对于用户或应用程序数据提供的值,请使用参数标记。在 pyodbc 中,? 是位置参数标记;单独传入值可使其与 SQL 文本保持分离。参数用于数据值,而不适用于表名或列名。如果标识符必须变化,请从固定的允许列表中选择,并按照 SQL Server 规则引用它。

典型的应用程序流程是先执行 connection = pyodbc.connect(connection_string),再执行 cursor = connection.cursor() 和 cursor.execute("SELECT name FROM dbo.Customers WHERE customer_id = ?", customer_id)。可以迭代 cursor 来处理各行;如果结果集足够小,也可以调用 fetchall()。对于大型结果集,应逐行处理。此查询假设所选数据库中存在指定的表和列;请根据你的架构替换它们。

connection = pyodbc.connect(connection_string) 成功后,将游标操作放在 try 块中,并在 finally 子句中关闭连接:try: ... finally: connection.close()。要清理游标,可在该代码块中使用 with connection.cursor() as cursor:;离开游标上下文时会关闭游标。pyodbc 的连接上下文(例如 with connection:)用于管理事务范围:正常退出时提交,异常逸出时回滚,但它不会关闭连接。你可以在 try 中组合使用事务上下文和游标上下文,然后在 finally 中调用 connection.close()。只要连接已成功打开,这样无论查询正常完成还是发生异常,连接都会在查询处理后关闭。如果要修改数据,请明确决定事务应在何处提交。此用法需要已配置的 SQL Server、驱动程序和架构;本文并未实际运行该用法。

诊断常见连接错误

如果 pyodbc 报告找不到驱动程序,请确认程序的运行环境中已安装 ODBC 驱动程序,并检查 Driver={...} 的值是否与注册名称完全一致,包括空格和版本号。如果无法连接到服务器,请检查 DNS 或主机名拼写、端口和实例设置、防火墙访问权限,以及 SQL Server 是否接受网络连接。超时通常表示网络连接问题或服务器负载较高;延长超时时间无法修正错误的目标地址。

如果登录失败,请确认连接实际使用的身份。受信任的身份验证使用进程身份,而 UID 和 PWD 使用 SQL 凭据;混用这两种方式可能导致发送错误的身份。然后检查数据库访问权限和数据库名称。遇到证书或加密错误时,请与管理员确认服务器证书链和驱动程序的加密设置,不要通过降低验证强度来绕过问题。最后,检查连接字符串是否缺少分号、驱动程序名称周围的花括号是否匹配、键名中是否意外带有空格,以及特殊字符是否已正确转义。诊断日志应提供有用信息,同时务必遮蔽密码和其他密钥。

有关驱动程序和连接字符串的详情,请参阅 pyodbc SQL Server 连接指南 和 pyodbc 官方文档。如需了解读取查询结果的相关示例,请参阅如何在 Python 中使用 fetchall() 从数据库提取元素。