从Python 3.4连接到远程MySQL数据库

时间:2016-04-25 06:28:56

标签: python mysql python-3.x ssh

我正在尝试使用Python 3.4同时连接到两个MySQL数据库(一个本地,一个远程),但我真的很挣扎。将问题分成三个:

  • 第1步:连接到本地数据库。这工作正常 使用PyMySQL。 (MySQLdb与Python 3.4不兼容 当然。)
  • 第2步:连接到远程数据库(需要 使用SSH)。我可以从Linux命令提示符开始工作,但不是 来自Python ...见下文。
  • 第3步:连接到两者 同时。我想我应该使用不同的端口 远程数据库,以便我可以同时拥有两个连接 但我不在这里!如果它是相关的那么两个DB将 有不同的名字。如果这个问题没有直接关系, 请告诉我,我会另外发布。

不幸的是,我并没有真正开始在适合新手的地方......一旦我能够开始工作,我可以愉快地回到基本的Python和SQL,但希望有人会对我表示同情并帮助我开始吧!

对于第2步,我的代码如下。它似乎非常接近回答这个问题sshtunnelPython - SSH Tunnel Setup and MySQL DB Access示例 - 尽管它使用了MySQLdb。目前我正在嵌入连接参数 - 一旦它正常工作,我会将它们移动到配置文件中。

import dropbox, pymysql, shlex, shutil, subprocess
from sshtunnel import SSHTunnelForwarder
import iot_config as cfg

def CloseLocalDB():
    localcur.close()
    localdb.close()

def CloseRemoteDB():
    # Disconnect from the database
#    remotecur.close()
#    remotedb.close()
    # Close the SSH tunnel
#    ssh.close()
    print("end of CloseRemoteDB function")

def OpenLocalDB():
    global localcur, localdb
    localdb = pymysql.connect(host=cfg.localdbconn['host'], user=cfg.localdbconn['user'], passwd=cfg.localdbconn['passwd'], db=cfg.localdbconn['db'])
    localcur = localdb.cursor()

def OpenRemoteDB():
    global remotecur, remotedb
    with SSHTunnelForwarder(
            ('my_remote_site', 22),
            ssh_username = "my_ssh_username",
            ssh_private_key = "/etc/ssh/my_private_key.ppk",
            ssh_private_key_password = "my_private_key_password",
            remote_bind_address = ('127.0.0.1', 3308)) as server:
        remotedb = None
#Following line gives an error if uncommented
#        remotedb = pymysql.connect(host='127.0.0.1', user='remote_db_user', passwd='remote_db_password', db='remote_db_name', port=server.local_bind_port)
        #remotecur = remotedb.cursor()

# Main program starts here
OpenLocalDB()
CloseLocalDB()
OpenRemoteDB()
CloseRemoteDB()

这是我得到的错误:

2016-04-21 19:13:33,487 | ERROR   | Secsh channel 0 open FAILED: Connection refused: Connect failed
2016-04-21 19:13:33,553 | ERROR   | In #1 <-- ('127.0.0.1', 60591) to ('127.0.0.1', 3308) failed: ChannelException(2, 'Connect failed')
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 60591)
Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/sshtunnel.py", line 286, in handle
    src_address)
  File "/usr/local/lib/python3.4/dist-packages/paramiko/transport.py", line 834, in open_channel
    raise e
paramiko.ssh_exception.ChannelException: (2, 'Connect failed')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.4/socketserver.py", line 613, in process_request_thread
    self.finish_request(request, client_address)
  File "/usr/lib/python3.4/socketserver.py", line 344, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python3.4/socketserver.py", line 669, in __init__
    self.handle()
  File "/usr/local/lib/python3.4/dist-packages/sshtunnel.py", line 296, in handle
    raise HandlerSSHTunnelForwarderError(msg)
sshtunnel.HandlerSSHTunnelForwarderError: In #1 <-- ('127.0.0.1', 60591) to ('127.0.0.1', 3308) failed: ChannelException(2, 'Connect failed')
----------------------------------------
Traceback (most recent call last):
  File "/home/pi/Documents/iot_pm2/iot_ssh_example_for_help.py", line 38, in <module>
    OpenRemoteDB()
  File "/home/pi/Documents/iot_pm2/iot_ssh_example_for_help.py", line 32, in OpenRemoteDB
    remotedb = pymysql.connect(host='127.0.0.1', user='remote_db_user', passwd='remote_db_password', db='remote_db_name', port=server.local_bind_port)
  File "/usr/local/lib/python3.4/dist-packages/pymysql/__init__.py", line 88, in Connect
    return Connection(*args, **kwargs)
  File "/usr/local/lib/python3.4/dist-packages/pymysql/connections.py", line 678, in __init__
    self.connect()
  File "/usr/local/lib/python3.4/dist-packages/pymysql/connections.py", line 889, in connect
    self._get_server_information()
  File "/usr/local/lib/python3.4/dist-packages/pymysql/connections.py", line 1190, in _get_server_information
    packet = self._read_packet()
  File "/usr/local/lib/python3.4/dist-packages/pymysql/connections.py", line 945, in _read_packet
    packet_header = self._read_bytes(4)
  File "/usr/local/lib/python3.4/dist-packages/pymysql/connections.py", line 981, in _read_bytes
    2013, "Lost connection to MySQL server during query")
pymysql.err.OperationalError: (2013, 'Lost connection to MySQL server during query')

提前致谢。

1 个答案:

答案 0 :(得分:1)

回答我自己的问题,因为在Github的J.M.Fernández的帮助下,我有一个解决方案:我在开头复制的示例使用端口3308但是端口3306是标准。一旦我改变它,它开始工作。