公司整套服务和数据库都是建立于阿里ECS,由于数据库设置了白名单只能内网访问 ,然而,作为一名"合格"的Python数据开发,每天要从Mysql、ES等拉大量的数据进行离线分析。
那么问题来了,链接服务器(跳板机)使用的是ssh校验,我的Pycharm不知为啥就是不能使用Deployment,私钥配置是没问题的(items直接ssh链接可以登陆,Navicat Premium隧道也可以链接内网数据库)。
所以每次都需要把写好的脚本scp到服务器然后在服务器上跑,跑完的csv文件之类的还有可能需要scp到本地(真的好麻烦阿!!!)
知道如何解决的大佬欢迎留言指点一下呀,于是就想着能不能偷个懒,在本地直接链接内网数据库拉数据到本地进行分析。
太大太大的数据还是别在本地这样玩了,Mac还是32G的香QAQ,接下来就不说废话贴代码了!!!
# -*- coding: UTF-8 -*-
import pymysql as mysql
from sshtunnel import SSHTunnelForwarder # pip install sshtunnel
import pandas as pd
"""
@Author: Tli
@File: 本地连接内网数据库
@Time: 2019-12-06 10:21
@Desc:
"""
class SshConnect(object):
"""本地ssh私钥校验连接内网数据库demo"""
def __init__(self):
self.server = SSHTunnelForwarder(('xxx.xx.xx.xxx', 22), # 服务器(跳板机)IP和端口
ssh_username="xx", # ssh用户名
ssh_pkey="/Users/xxx/.ssh/id_rsa", # 私钥文件绝对定位
ssh_private_key_password="", # 密码
remote_bind_address=("xxx.xx.xx.xxx", 3306)) # 内网数据库IP及端口
self.server.start() # 启动连接管道
self.db = mysql.connect(host='127.0.0.1', # 这里固定填这个不用改
port=self.server.local_bind_port, # 这里固定填这个不用改
user="xxx", # 连接数据库用户名
passwd="xxxxxxxxxxxx", # 连接数据库密码
db="xxxx") # 连接的库名
self.cursor = self.db.cursor() # 获取数据库游标
def __del__(self):
try:
self.cursor.close() # 关闭游标
self.db.close() # 关闭数据库连接
self.server.close()
except Exception:
pass
def data_handle(self):
"""举个小例子,更多的PyMysql和Pandas操作请自行百度一下"""
self.cursor.execute("select * from xxx where id = 1")
ret = self.cursor.fetchone()
print(ret)
ret_df = pd.read_sql("select xxx,xxx,xxx from xxx where id in (1,2,3,4,5)", self.db)
ret_df.to_csv('Users/xxx/Desktop/xxx.csv', index=0)
class CodeConnect(object):
"""本地ssh密码连接内网数据库demo"""
def __init__(self):
self.server = SSHTunnelForwarder(('xxx.xx.xx.xxx', 22), # 服务器(跳板机)IP和端口
ssh_username='xxx', # 服务器(跳板机)用户名
ssh_password='xxxxxx', # 服务器(跳板机)密码
remote_bind_address=('xxx.xx.xx.xxx', 3306)) # 内网数据库IP及端口
self.server.start() # 启动连接管道
self.db = mysql.connect(host='127.0.0.1',
port=self.server.local_bind_port,
user='xxx',
passwd='xxxxx',
db='xxx')
self.cursor = self.db.cursor() # 获取数据库游标
def __del__(self):
try:
self.cursor.close()
self.db.close()
self.server.close()
except Exception:
pass