今天同事找到我说,他用pyton连接不上数据库。出于安全考虑,我们的数据库不允许直连,需要通过跳板机进行连接。所以,我认为是他没有使用ssh隧道。结果看了代码后,发现使用了sshtunnel模块的。

    将他的代码拿来后,自己运行了一遍。也是报错(2013, 'Lost connection to MySQL server during query')。以为是网络原因,又接着运行了几遍,还是报相同的错误。核对了下,连接信息都没问题的,检查网络,也没发现异常。顿时傻眼了,不知所措。就先去解决其他问题了。晚上回到家后,有着强迫症的我,又重新打开了代码,端详了起来。

    

with SSHTunnelForwarder(
         (ip, port),    #B机器的配置
         ssh_username="user",
         ssh_password="password",
         remote_bind_address=('ip', port)
         #logger=create_logger(loglevel=1)
) as server:
    conn = MySQLdb.connect(host='127.0.0.1',
			   port=server.local_bind_port,
			   username='username'
			   password='password'
			   db='db'
			   charset='utf8'	)
cursor = conn.cursor()
sql = 'select * from test limit 1'

如上代码,一开始并没发觉哪里不对,但后来看到那个报错,又想到前几天看到python中with的用法,似乎有了眉目。将sql代码放在with块里边执行。一切都OK了,瞬间觉得恍然大悟。这和with语句的特性密不可分。with 语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭、线程中锁的自动获取和释放等。


详细见https://www.ibm.com/developerworks/cn/opensource/os-cn-pythonwith/index.html