You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过堡垒机端口转发从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 02:27:02