Python通过跳板机访问数据库的方法

什么是跳板机?

跳板机(Jump Server):也称堡垒机,是一类可作为跳板批量操作的远程设备的网络设备,是系统管理员和运维人员常用的操作平台之一。
那么具体是做什么的呢?
现在一些比较大的互联网企业,往往拥有大量的服务器,为了能够统一方便管理,运维人员通过跳板机去管理对应的服务器。我们在访问服务器的时候,先通过登陆跳板机,然后再进入相应服务器。从一定程度上提升了服务器的数据安全性,也提升了服务器的可维护性。

sshtunnel 连接堡垒机

跳板机的本质还是ssh连接,通过paramiko 自己造轮子的话理论也是可以实现的,这边推荐 sshtunnel 这个包,省的自己写了。
理解了跳板机的原理,这边的配置就比较好理解了。拿这张图举例,首先需要先访问跳板机,其实就是最常见的ssh连接,可以是账户密码,也可以是密钥登录的,如果是密钥的话需要在 跳板机的.ssh 目录下的某个许可文件中添加上自己的公钥

最后还需要补充一下 目标主机的ip 和端口。理解了这些,以下的这些参数就知道怎么配置了,
local_bind_address 可以不配置,不配置会随机获取本地的端口号,如果指定的话就会占用本地固定的端口号,推荐配置这一参数。
填写本地的端口是因为这边会将目标服务器ip的端口映射为本地端口,然后访问本地端口就能实现目标端口的访问了。

from sshtunnel import SSHTunnelForwarder
server = SSHTunnelForwarder(
        (host_jump, int(port_jump)),  # 跳板机的配置
        ssh_pkey=ssh_pk_jump,
        #密钥的访问方式,如果是密码 ssh_password=???
        ssh_username=user_name_jump,
        remote_bind_address=(host_mysql, int(port_mysql)))  # 数据库服务器的配置
        local_bind_address=(local_ip, local_port)  # 开启本地转发端口
        )
	server.start()
	server.close()

有些人习惯用 上下文管理器,看起来更舒服些

from sshtunnel import SSHTunnelForwarder
with SSHTunnelForwarder(
        (host_jump, int(port_jump)),  # 跳板机的配置
        ssh_pkey=ssh_pk_jump,
        #密钥的访问方式,如果是密码 ssh_password=???
        ssh_username=user_name_jump,
        remote_bind_address=(host_mysql, int(port_mysql)))  # 数据库服务器的配置
        local_bind_address=(local_ip, local_port)  # 开启本地转发端口
        )as server
	server.start()

连接数据库

建立好通道后就能通过本地映射的端口访问目标的数据库端口了。
常见的mysql 数据库访问 比如 mysqldb,pymysql,mysql.connector,
mysqldb跟 pymysql 差不多,只不过前者适用python2的版本,后者适用python3的版本,mysql.connector是官方推荐的。
pymysql 跟 mysql.connector 还是有一些区别的
我这边使用的是 mysql.connector ,在实践中老是无法连接上,而pymysql却是可以的。
最终终于找到了解决办法。。。

以下是我的mysql.connector 连接数据库的样例。

with SSHTunnelForwarder(
        (host_jump, int(port_jump)),  # 跳板机的配置
        ssh_pkey=ssh_pk_jump,
        #密钥的访问方式,如果是密码 ssh_password=???
        ssh_username=user_name_jump,
        remote_bind_address=(host_mysql, int(port_mysql)))  # 数据库服务器的配置
        local_bind_address=(local_ip, local_port)  # 开启本地转发端口
        )as server
	server.start()
    conn = mysql.connector.connect(**{'host': '127.0.0.1',
                              'port': server.local_bind_port,
                              'user': dbcfg["user"],
                              'password': dbcfg["password"],
                              'db': dbcfg["db"],
                              'charset': dbcfg["charset"],
                              'collation': dbcfg["collation"],
                              'use_unicode': dbcfg["use_unicode"],
                              'use_pure': True})
        cursor = conn.cursor(dictionary=True)
        cursor.execute(sql, params)
        rows = cursor.fetchall()
        # conn.commit()
        cursor.close()
        conn.close()

这样,数据库就能正常访问啦

代码重构和优化

首先,就上面这样的代码而言,在每次查询都需要进行跳板机的连接,对于短时间突然大量请求的情况,这种是效率极低的。所以最好是能够将建立管道保存下来。
其次,如果同时访问多种数据库的情况,存在有无跳板机的场景,所以最好能够先将所有的数据库都进行连接,将conn保存在字典中,根据要访问的机器调用对应的conn,最后再统一释放。

def get_slave_conn_byProxy(dbcfg):
    server = SSHTunnelForwarder(
        eval(dbcfg["addr"]),
        ssh_username=dbcfg["ssh_username"],
        ssh_pkey=os.getenv("HOME") + "/.ssh/id_rsa",
        remote_bind_address=eval(dbcfg["remote_bind_address"]),
        local_bind_address=eval(dbcfg["local_bind_address"])  # 开启本地转发端口
    )
    server.start()
    conn = get_db_connection({'host': '127.0.0.1',
                              'port': server.local_bind_port,
                              'user': dbcfg["user"],
                              'password': dbcfg["password"],
                              'db': dbcfg["db"],
                              'charset': dbcfg["charset"],
                              'collation': dbcfg["collation"],
                              'use_unicode': dbcfg["use_unicode"],
                              'use_pure': True})
    return server, conn

def get_db_connection(dbcfg):
    # logger.info(f"============ debug db config: {dbcfg}")
    conn = mysql.connector.connect(**dbcfg)
    return conn

# 通过输入的连接参数判断是否需要通过跳板机的方式
def get_slave_conn(dbcfg):
    if "addr" in dbcfg:
        return get_slave_conn_byProxy(dbcfg)
    else:
        conn = get_db_connection(dbcfg)
        return None, conn

def read_slave_db_data(sql, conn, params=None, use_pdf=True):
        cursor = conn.cursor(dictionary=True)
        cursor.execute(sql, params)
        rows = cursor.fetchall()
        # conn.commit()
        cursor.close()
        if use_pdf:
            return pd.DataFrame(rows)
        else:
            return rows

到此这篇关于Python通过跳板机访问数据库的文章就介绍到这了,更多相关Python跳板机访问数据库内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • python利用跳板机ssh远程连接redis的方法

    公司服务器的mysql和redis连接都需要有跳板机,网上有很多python ssh远程连接mysql的,那天我研究了下,利用sshtunnel模块连接上了redis,具体如下: from sshtunnel import SSHTunnelForwarder # ssh连接库 import redis # redis模块 server = SSHTunnelForwarder( ssh_address_or_host= , # ssh地址 ssh_username= , # ssh连接的用户名

  • Python通过跳板机访问数据库的方法

    什么是跳板机? 跳板机(Jump Server):也称堡垒机,是一类可作为跳板批量操作的远程设备的网络设备,是系统管理员和运维人员常用的操作平台之一. 那么具体是做什么的呢? 现在一些比较大的互联网企业,往往拥有大量的服务器,为了能够统一方便管理,运维人员通过跳板机去管理对应的服务器.我们在访问服务器的时候,先通过登陆跳板机,然后再进入相应服务器.从一定程度上提升了服务器的数据安全性,也提升了服务器的可维护性. sshtunnel 连接堡垒机 跳板机的本质还是ssh连接,通过paramiko 自

  • Python操作Sql Server 2008数据库的方法详解

    本文实例讲述了Python操作Sql Server 2008数据库的方法.分享给大家供大家参考,具体如下: 最近由于公司的一个项目需要,需要使用Sql Server 2008数据库,开发语言使用Python,并基于windows平台上的Wing IDE4.0进行. 之前并未使用过Sql Server数据库,这次也当作一次练手,并把这次数据库前期开发过程中遇到的一些问题进行记录. 一.关于pyodbc库和pymssql库的选择 在使用python语言进行开发之前,需要确定使用哪种第三方的数据库操作

  • Spring Boot集成MyBatis访问数据库的方法

    基于spring boot开发的微服务应用,与MyBatis如何集成? 集成方法 可行的方法有: 1.基于XML或者Java Config,构建必需的对象,配置MyBatis. 2.使用MyBatis官方提供的组件,实现MyBatis的集成. 方法一 建议参考如下文章,完成集成的验证. MyBatis学习 之 一.MyBatis简介与配置MyBatis+Spring+MySql 基于Spring + Spring MVC + Mybatis 高性能web构建 spring与mybatis三种整合

  • VC基于ADO技术访问数据库的方法

    本文实例讲述了VC基于ADO技术访问数据库的方法.分享给大家供大家参考.具体如下: 一.在StdAfx.h文件中添加 复制代码 代码如下: #import "C:/Program Files/Common Files/System/ado/msado15.dll" no_namespace rename("EOF","rsEOF") 导入ADO引擎. 二.数据库应用层操作 void CADOExample1Dlg::OnBtnQuery() {

  • python统计日志ip访问数的方法

    本文实例讲述了python统计日志ip访问数的方法.分享给大家供大家参考.具体如下: import re f=open("/tmp/a.log","r") arr={} lines = f.readlines() for line in lines: ipaddress=re.compile(r'^#(((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?))') match=ipaddres

  • python连接、操作mongodb数据库的方法实例详解

    本文实例讲述了python连接.操作mongodb数据库的方法.分享给大家供大家参考,具体如下: 数据库连接 from pymongo import MongoClient import pandas as pd #建立MongoDB数据库连接 client = MongoClient('162.23.167.36',27101)#或MongoClient("mongodb://162.23.167.36:27101/") #连接所需数据库,testDatabase为数据库名: db=

  • Python操作SQLite/MySQL/LMDB数据库的方法

    1.概述 1.1前言 最近在存储字模图像集的时候,需要学习LMDB,趁此机会复习了SQLite和MySQL的使用,一起整理在此. 1.2环境 使用win7,Python 3.5.2. 2.SQLite 2.1准备 SQLite是一种嵌入式数据库,它的数据库就是一个文件.Python 2.5x以上版本内置了SQLite3,使用时直接import sqlite3即可. 2.2操作流程 概括地讲,操作SQLite的流程是: ·通过sqlite3.open()创建与数据库文件的连接对象connectio

  • Python 解析pymysql模块操作数据库的方法

    pymysql 是 python 用来操作MySQL的第三方库,下面具体介绍和使用该库的基本方法. 1.建立数据库连接 通过 connect 函数中 parameter 参数 建立连接,连接成功返回Connection对象 import pymysql #建立数据库连接 connection = pymysql.connect(host = 'localhost', user = 'root', password = '123456', database = 'mydb', charset =

  • Python中设置变量访问权限的方法

    在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑. 但是,从前面Student类的定义来看,外部代码还是可以自由地修改一个实例的name.score属性: >>> bart = Student('Bart Simpson', 98) >>> bart.score 98 >>> bart.score = 59 >>> bart.score 59 如果要让内部属性不被外部

随机推荐