1.说明

mysql(或其他数据库,如postgresql)部署在一台服务器上,但不能直接连接该服务器(为了安全),需要通过一台跳板机才能访问,该跳板机是可以通过SSH秘钥访问的。我们可以借助paramiko这个包里面的SSHTunnelForwarder进行连接

2.代码

连接MySQL的Python库有好几个,我这里使用pymysql

2.1 连接MySQL

import paramiko
import pymysql
from sshtunnel import SSHTunnelForwarder


def get_tunnel_ssh(config_dict):
    private_key = paramiko.RSAKey.from_private_key_file(filename=config_dict.get("ssh_key_path"),
                                                        password=config_dict.get("ssh_password"))
    ssh_tunnel = SSHTunnelForwarder(ssh_address_or_host=(config_dict.get("ssh_ip"), config_dict.get("ssh_port")),
                                    ssh_username=config_dict.get("ssh_user"),
                                    ssh_pkey=private_key,
                                    remote_bind_address=(config_dict.get("ip"), config_dict.get("port")))
    ssh_tunnel.start()
    # ssh_tunnel.close()
    return ssh_tunnel


def get_mysql_conn():
    ssh_config = {
        'ip': '47.241.XX.XX',
        'port': 3306,
        'ssh_ip': '23.248.XX.XX',
        'ssh_port': 6666,
        'ssh_user': 'pan',
        'ssh_password': 'Tcjo5XXXXX',
        'ssh_key_path': r"E:\pan\dingding\key",
    }
    mysql_config = {
        "host": "127.0.0.1",
        "port": None,
        "user": "pan",
        "passwd": "&B2dpzXXXXX",
        "db": "walletdb3",
        "charset": "utf8mb4",
    }
    tunnel = get_tunnel_ssh(ssh_config)
    mysql_config.update({"port": tunnel.local_bind_port})  # 注意mysql端口使用的是隧道的端口
    print(mysql_config)
    mysql_conn = pymysql.connect(**mysql_config)
    return mysql_conn

2.2 连接postgresql

如果要连接postgresql,我们可以使用psycopg2这个库,示例如下

import paramiko
import psycopg2
from psycopg2.extras import RealDictCursor
from sshtunnel import SSHTunnelForwarder


def get_tunnel_ssh(config_dict):
    private_key = paramiko.RSAKey.from_private_key_file(filename=config_dict.get("ssh_key_path"),
                                                        password=config_dict.get("ssh_password"))
    ssh_tunnel = SSHTunnelForwarder(ssh_address_or_host=(config_dict.get("ssh_ip"), config_dict.get("ssh_port")),
                                    ssh_username=config_dict.get("ssh_user"),
                                    ssh_pkey=private_key,
                                    remote_bind_address=(config_dict.get("ip"), config_dict.get("port")))
    ssh_tunnel.start()
    # ssh_tunnel.close()
    return ssh_tunnel


def get_postgresql_conn():
    ssh_config = {
        'ip': 'some-domain.rds.amazonaws.com',  # 数据库的URL
        'port': 5432,  # 数据库的端口
        'ssh_ip': 'jump.testdomain.io',  # 跳板机的IP
        'ssh_port': 22,  # 跳板机的端口
        'ssh_user': 'readonly',  # 跳板机的用户名
        'ssh_key_path': r"/Users/grantit/.ssh/id_rsa",  # 登录跳板机的私钥文件
        'ssh_password': 'your pri passwd',  # 私钥文件对应的密码

    }

    tunnel = get_tunnel_ssh(ssh_config)

    db_config = {
        "database": "crawler",  # 数据库名
        "user": "postgres",  # 连接数据库的用户
        "password": "you password",  # 连接数据库的密码
        "host": "127.0.0.1",  # 固定
        "port": tunnel.local_bind_port  # 固定
    }

    conn = psycopg2.connect(**db_config)
    return conn


if __name__ == '__main__':
    get_postgresql_conn()

3.使用方法

使用上面封装的方法获取到数据库链接之后,再获取对应的cursor就可以获取数据了,具体用法可以看看不同库的使用

from utils.ssh_mysql import get_mysql_conn

mysql_conn = get_mysql_conn()
cursor = mysql_conn.cursor()
cursor.execute("select * from eth_balance_guarder order by id desc limit 1;")
data = cursor.fetchall()
print(data)
cursor.close()
mysql_conn.close()

关于mysql的使用可以参考
【python】python连接mysql数据库(pymysql)

如果你用的JS而不是Python,可以参考一下另一篇文章
【js】SSH隧道远程连接mysql

更多推荐