如何通过堡垒机端口转发从Python脚本连接RDS SQL Server实例
问题根因定位
- 连接字符串语法错误:你把
autocommit参数写到了ODBC连接字符串内部,这个参数是pyodbc.connect()的独立入参,不属于连接字符串内容,会导致参数解析错误。 - ODBC驱动名称不匹配:你本地安装的是「ODBC Driver 17 for SQL Server」,但连接字符串里写的是无版本号的通用名称,Mac环境下驱动必须写完整带版本的名称才能被识别。
- 代码逻辑错误:调用
cursor.execute前没有通过sql_connect.cursor()创建游标对象,会直接抛出未定义变量错误。 - 可选问题:如果手动运行SSH端口转发后没有保持终端进程存活,或者SSH连接中断,也会导致连接超时。
解决方案
分为两种场景,可根据你的使用需求选择:
场景1:手动维持SSH端口转发存活(即你原来的操作流程)
先确认SSH转发命令正常运行、终端未关闭,且可以通过本地数据库工具正常连接localhost:20004,再修改代码如下:
import pyodbc import pandas as pd # 打印本地驱动列表,确认驱动名称和你实际安装的版本匹配 print(pyodbc.drivers()) # 修正连接字符串:移除内部的autocommit参数,修改驱动名 conn_str = "Driver={ODBC Driver 17 for SQL Server};SERVER=localhost,20004;DATABASE=simpsons;UID=my_user;PWD=my_pwd" # autocommit作为connect方法的独立参数传入 sql_connect = pyodbc.connect(conn_str, autocommit=True) # 先创建游标再执行SQL cursor = sql_connect.cursor() cursor.execute("select * from spp.transactions where acx_num > 1000") # 测试获取数据 rows = cursor.fetchall() print(rows)
场景2:Python代码自动完成堡垒机端口转发+数据库连接(无需手动开SSH)
不需要单独开终端运行SSH命令,代码自动处理端口转发生命周期,需要先安装依赖:pip install sshtunnel
修改代码如下:
import pyodbc import pandas as pd from sshtunnel import SSHTunnelForwarder # 堡垒机配置 BASTION_HOST = "my_bastion_host.com" BASTION_USER = "knn0926" # 堡垒机认证支持密码/私钥两种方式,示例用私钥,用密码的话替换为ssh_password参数即可 BASTION_PRIVATE_KEY = "~/.ssh/id_rsa" # 替换为你本地的私钥路径 # RDS配置 RDS_ENDPOINT = "targeted-mssql-rds.aws.com" RDS_PORT = 1433 RDS_USER = "my_user" RDS_PWD = "my_pwd" RDS_DB = "simpsons" with SSHTunnelForwarder( (BASTION_HOST, 22), ssh_username=BASTION_USER, ssh_pkey=BASTION_PRIVATE_KEY, local_bind_address=('127.0.0.1', 20004), remote_bind_address=(RDS_ENDPOINT, RDS_PORT) ) as tunnel: print(f"端口转发已建立,本地绑定端口:{tunnel.local_bind_port}") # 连接数据库 conn_str = "Driver={ODBC Driver 17 for SQL Server};SERVER=localhost,20004;DATABASE=simpsons;UID=my_user;PWD=my_pwd" sql_connect = pyodbc.connect(conn_str, autocommit=True) cursor = sql_connect.cursor() cursor.execute("select * from spp.transactions where acx_num > 1000") rows = cursor.fetchall() print(rows) # 所有数据库操作都要放在with代码块内,with块结束后端口转发会自动关闭
额外注意事项
- Mac环境如果首次连接堡垒机没有添加host密钥到本地known_hosts,sshtunnel可能报错,可以在SSHTunnelForwarder参数中添加
host_pkey_directories=None跳过校验,或者手动SSH登录一次堡垒机完成密钥确认。 - 确认RDS安全组放通了堡垒机的1433端口访问权限,堡垒机安全组放通了你本地IP的22端口访问权限。
内容的提问来源于stack exchange,提问作者cocktail Enthusiast
相关产品推荐
相关产品推荐

