简体   繁体   English

使用 python 3 通过 SSH(通过跳转主机)连接到 MySQL 数据库

[英]Connecting to MySQL database via SSH (over a jump host) using python 3

I am trying to build a connection between python and my MySQL-Database (which is in AWS).我正在尝试在 python 和我的 MySQL 数据库(位于 AWS 中)之间建立连接。

The SSH tunnel works fine, the matters happens if its about starting the connection to the database afterwards. SSH 隧道工作正常,如果之后启动与数据库的连接,就会发生这种情况。 Here is my code:这是我的代码:

from sqlalchemy import create_engine from sshtunnel import SSHTunnelForwarder从 sqlalchemy 导入 create_engine 从 sshtunnel 导入 SSHTunnelForwarder

Here is my code:这是我的代码:

tunnel = SSHTunnelForwarder(
    ('ssh-host', 22),
    ssh_pkey="my-keypair",
    ssh_username="my-user",
    ssh_password="my-pw",
    remote_bind_address=('database-host', db-port)
    )

tunnel.start()
print("SSH connection created..")   #until here it works fine.
port = str(tunnel.local_bind_port)
engine = create_engine("mysql+pymysql://db-username:db-pw@db-url"+port+"/dbname",encoding='latin1', echo=True, pool_recycle=280)
connection = engine.connect()

After I try to connect to the database it shows following error:在我尝试连接到数据库后,它显示以下错误:

sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on db-url sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on db-url

Before I created a jump host, the connection string worked fine.在我创建跳转主机之前,连接字符串工作正常。

With this statement:有了这个声明:

tunnel = SSHTunnelForwarder(
    ('ssh-host', 22),
    ssh_pkey="my-keypair",
    ssh_username="my-user",
    ssh_password="my-pw",
    remote_bind_address=('database-host', db-port)
    )

An SSH tunnel is established to the ssh server at ssh-host on port 22 and the remote tunnel endpoint is instructed to connect to the database server running on database-host on port db-port (eg 3306). SSH 隧道在ssh-host的端口 22 上建立到 ssh 服务器,并指示远程隧道端点连接到在端口db-port上的数据库主机上运行的数据库服务器(例如 3306)。 But the essential point to note is that this tunnel is only established once the client makes the connection.但需要注意的重要一点是,该隧道仅在客户端建立连接后才建立。

But how does the client make the connection, you may ask?但是您可能会问,客户端是如何建立连接的? Well, part of the functionality of the SSHTunnelForwarder is that it listens for connections on a random port on the localhost.嗯,SSHTunnelForwarder 的部分功能是它监听本地主机上随机端口上的连接。 So when you connect to localhost using your client application (this is what happens in the create_engine() and engine.connect() calls), the SSH tunnel will read data from that connection, push it across the tunnel and deliver it to the remote endpoint on that side of the tunnel (ie the database server at database-host:db-port).因此,当您使用客户端应用程序连接到 localhost 时(这是create_engine()engine.connect()调用中发生的情况),SSH 隧道将从该连接读取数据,将其推送到隧道并将其传递到远程隧道那一侧的端点(即位于 database-host:db-port 的数据库服务器)。

So what you are missing in your code is that the database connection should be targeting localhost, as in the following (you should be able to use the IP address 127.0.0.1 or the hostname localhost ):因此,您在代码中缺少的是数据库连接应该以 localhost 为目标,如下所示(您应该能够使用 IP 地址 127.0.0.1 或主机名localhost ):

engine = create_engine("mysql+pymysql://db-username:db-pw@127.0.0.1:"+port+"/dbname",encoding='latin1', echo=True, pool_recycle=280)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM