通过sshtunner连接数据库:

代码如下:

import pymysql
from sshtunnel import SSHTunnelForwarder
with SSHTunnelForwarder(
('123.88.12.1',22),  # 指定ssh登录的跳转机的address,端口号
ssh_username='user',  # 远程服务器的用户名,注意不是DB的用户名和密码
ssh_password='pwd123',# 远程服务器的密码
remote_bind_address=('123.88.199.198',3306) #注意端口号不要加引号
local_bind_address=('127.0.0.1',13306) #注意端口号不要加引号
) as server: # mysql服务器的address,端口号
conn = pymysql.connect(host='127.0.0.1',  # 注意此处为上述代码中的local_bind_address 中的地址和端口号
port=server.local_bind_port,
user='dbuser',  # 数据库用户名
passwd='dbpwd123', # 数据库密码
charset='utf8',
db='dbname',# 数据库名称
autocommit=True)# 如果修改数据库自动提交
cursor = conn.cursor(pymysql.cursors.DictCursor)
cursor.execute("SELECT * FROM table where name='xiaoming';")
result=cursor.fetchall()
print(result)
cursor.close()#关闭游标
conn.close()#关闭连接
如果密码中包含特殊字符,比如反斜杠,注意一定要对反斜杠进行转义
代码理解:


首先通过 sshtunnel.SSHTunnelForwarder 进行端口映射,将远程服务器的3306端口映射到本地的13306端口,再连接本地的端口,那么后续对本地13306端口的操作其实都可以视为对线上服务器3306端口的操作,理论上来说,PuTTY也是进行了相同的操作,以此达到内网穿透的目的


 

下边这个是别人写好的,直接可以使用的情况;如果不这样写的话,脱离with as的作用于,连接就关闭了,这样导致连接不上DB

import pymysql
from sshtunnel import SSHTunnelForwarder
#通过SSH,连接远程服务器的数据库
class DataBaseHandle :
''' 定义一个 MySQL 操作类'''
def __init__ ( self , host='127.0.01' , username='xxx' , password='xxx'
, database='xxx' , port=10022 ) :
'''初始化数据库信息并创建数据库连接'''
self.w_server = SSHTunnelForwarder (
# 中间服务器地址
("xxx.64.47.xxx" , 22) ,#远程服务器的地址和端口号
ssh_username="xxx" ,
ssh_pkey="~/.ssh/id_rsa" ,
# ssh_private_key_password="~/.ssh/id_rsa",
# 目标的地址与端口,因为目标地址就是中间地址所以写127.0.0.1或者localhost
remote_bind_address=('192.163.11.11' , 3306) ,#DB的服务器的地址和端口号
# 本地的地址与端口
local_bind_address=('127.0.0.1' , 10022) #本地的映射的地址和端口号
)
# 启动ssh实例,后续的MySQL网络连接都将在这个环境下运行。
self.w_server.start ()
# 后面开始对MySQL的数据进行初始化
self.host = host
self.username = username
self.password = password
self.database = database
self.port = port
self.db = pymysql.connect ( host=self.host ,
user=self.username ,
password=self.password ,
database=self.database ,
port=self.port ,
charset='utf8' )
#  这里 注释连接的方法,是为了 实例化对象时,就创建连接。不许要单独处理连接了。
#
# def connDataBase(self):
#     ''' 数据库连接 '''
#
#     self.db = pymysql.connect(self.host,self.username,self.password,self.port,self.database)
#
#     # self.cursor = self.db.cursor()
#
#     return self.db
def insertDB ( self , sql ) :
''' 插入数据库操作 '''
self.cursor = self.db.cursor ()
try :
# 执行sql
self.cursor.execute ( sql )
# tt = self.cursor.execute(sql)  # 返回 插入数据 条数 可以根据 返回值 判定处理结果
# print(tt)
self.db.commit ()
except :
# 发生错误时回滚
self.db.rollback ()
finally :
self.cursor.close ()
def deleteDB ( self , sql ) :
''' 操作数据库数据删除 '''
self.cursor = self.db.cursor ()
try :
# 执行sql
self.cursor.execute ( sql )
# tt = self.cursor.execute(sql) # 返回 删除数据 条数 可以根据 返回值 判定处理结果
# print(tt)
self.db.commit ()
except :
# 发生错误时回滚
self.db.rollback ()
finally :
self.cursor.close ()
def updateDb ( self , sql ) :
''' 更新数据库操作 '''
self.cursor = self.db.cursor ()
try :
# 执行sql
self.cursor.execute ( sql )
# tt = self.cursor.execute(sql) # 返回 更新数据 条数 可以根据 返回值 判定处理结果
# print(tt)
self.db.commit ()
except :
# 发生错误时回滚
self.db.rollback ()
finally :
self.cursor.close ()
def selectDb ( self , sql ) :
''' 数据库查询 '''
self.cursor = self.db.cursor ()
try :
self.cursor.execute ( sql )  # 返回 查询数据 条数 可以根据 返回值 判定处理结果
data = self.cursor.fetchall ()  # 返回所有记录列表
print ( data )
# 结果遍历
for row in data :
sid = row[0]
name = row[1]
# 遍历打印结果
print ( 'sid = %s,  name = %s' % (sid , name) )
except :
print ( 'Error: unable to fecth data' )
finally :
self.cursor.close ()
def closeDb ( self ) :
''' 数据库连接关闭 '''
self.db.close ()
self.w_server.close ()
if __name__ == '__main__' :
DbHandle = DataBaseHandle ()
DbHandle.selectDb ( 'SELECT VERSION()' )
DbHandle.closeDb ()
https://www.cnblogs.com/sidianok/p/12571798.html 相关参考
https://blog.csdn.net/zgbzbl/article/details/107081320 相关参考