一、问题需求
对于有ssh通道设置的数据库连接,遇到已经有一段时间了。之前老是疑惑,使用Navicat之类的工具就可以连接数据库,但用python就是连接不到。之前写的博文【python连接PostgreSQL数据库获取数据的办法】怎么灰事,就不适用了。今日有空,把这个问题拉出来,解决一下:对于设置有ssh通道的数据库,该怎么用python来连接?
二、解决办法
从网上看了一大圈,尝试了好几篇博文提供的方法,都没有达到自己想要的结果。最后,发现了一篇有用的博文1,借助它的说明,终于成功连接。回顾一下,ssh有点像堡垒机,或者说第三方,博文【python连接PostgreSQL数据库获取数据的办法】介绍的这些连接方式,可以认为连接数据库,只有两方。现在多了一个中间方,从而来连接你和数据库。可以参考通过Navicat连接数据库的界面比较形象化得知。

python提供了很好的包工具,可以快速实现这种设置了ssh通道的数据库的连接。你可能还没有需要的包:sshtunnel,安装方式很简单的:
pip install --user sshtunnel
如果你觉得安装慢,那就可以用这种方式:
pip install sshtunnel -i https://pypi.douban.com/simple
详细介绍可以参考博文【使用pip install xxxx库 命令安装速度太慢解决小妙招】
完成上述操作,具体连接方式,请参考下方的具体实现方式,及备注信息。
## python通过ssh通道连接PostgreSQL
from sshtunnel import SSHTunnelForwarder
import psycopg2
import pandas as pd
server = SSHTunnelForwarder(
# 指定ssh登录的跳转机的address
ssh_address_or_host=('ssh_ip', '端口号'),# 分别对应填写上图中的 1 , 2 位置的参数
ssh_username='ssh_username', # 对应上图的 3 位置的参数,即ssh用户名
#设置密钥
ssh_password = 'ssh_password', # 对应上图的 4 位置的参数,即ssh用户密码
# 设置数据库服务地址及端口
remote_bind_address=('database_ip' , '端口号')) # 要连接的数据库地址、端口号,分别对应下图中的 1,2 位置的参数
server.start()
conn = psycopg2.connect(database = 'databasename', # 要连接的数据库名,对应下图的 3 位置的参数
user = 'username', # 要连接的数据库的用户名,对应下图的 4 位置的参数
password = 'password', #要连接的数据库的用户密码,对应下图的 5 位置的参数
host = '127.0.0.1', # 此处必须是是127.0.0.1
port = server.local_bind_port)
sql = 'select * from mgmt_etl.e_data_intfc '
e_data_intfc = pd.read_sql(sql,con = conn)
e_data_intfc.head()

使用完后,切记要将服务关闭!
server.close()
【备注】:代码或图中的信息皆为自己临时随手填写,以便和代码中相关信息映射参考。实际连接,请使用自己的相关库信息进行替代即可。欢迎下方留言,交流学习。
我的代码
## python通过ssh通道连接PostgreSQL
from sshtunnel import SSHTunnelForwarder
import psycopg2
import psycopg2.extras
import logging
logger = logging.getLogger('log')
class ConnectPG:
"""
连接至华为云PG库
"""
server = SSHTunnelForwarder(
# 指定ssh登录的跳转机的address
ssh_address_or_host=('124.70.94.***', 22), # ip, 端口
ssh_username='root', # ssh用户名
# 设置密钥
ssh_password='******', # ssh用户密码
# 设置数据库服务地址及端口
remote_bind_address=('127.0.0.1', 5432)) # 要连接的数据库地址、端口号
def connect(self):
for _ in range(10):
try:
self.server.start()
conn = psycopg2.connect(database='qdp', # 要连接的数据库名
user='postgres', # 要连接的数据库的用户名
password='***', # 要连接的数据库的用户密码
host='127.0.0.1', # 此处必须是是127.0.0.1
port=self.server.local_bind_port)
cursor = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
return conn, cursor
except Exception as err:
logger.exception("数据库连接失败, %s" % err)
return None, None
def query(self, sql):
conn, cursor = self.connect()
try:
cursor.execute(sql)
results = cursor.fetchall()
except Exception as err:
logger.error(err)
results = []
cursor.close()
conn.close()
self.server.close()
return results
if __name__ == '__main__':
sql = """SELECT * FROM formtables.qyyhxx"""
result = ConnectPG().query(sql)
print(result)
本文转自 https://blog.csdn.net/weixin_42521211/article/details/115505299,如有侵权,请联系删除。