【问题标题】:Conecting to MySQL in a remote server from python从 python 连接到远程服务器中的 MySQL
【发布时间】:2017-08-01 06:54:41
【问题描述】:

我在 MacOS X 10.12 上使用 Python 3.5、pymysql 0.7.6。

我正在尝试使用 python 访问远程服务器中的 MySQL 数据库。我可以使用以下命令从命令行访问:

ssh root@XXX.XXX.XXX.XXX
root@XXX.XXX.XXX.XXX's password: my_server_password

然后在服务器中:

mysql my_database -p
Enter password: my_database_password

它有效,我可以用我的数据库做各种事情。现在,我尝试在 python 中做同样的事情,遵循文档或我在其他帖子中找到的大量示例:

import pymysql

cnx = pymysql.connect(host='XXX.XXX.XXX.XXX', port='3306', user='root', password='my_server_password', db='my_database')

它不起作用,出现错误:

pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'XXX.XXX.XXX.XXX' ([Errno 61] Connection refused)")

凭据是正确的凭据,我已检查该端口是否是正确的端口,正如其他帖子中所建议的那样。我怀疑它可能与也有密码的数据库有关,而不仅仅是服务器,但我还没有找到包含两个密码的任何方法。实际上,我不确定连接命令中应该包含哪个密码,是服务器密码还是数据库密码。它不适用于他们俩。

那么,您对这里可能出现的问题有什么建议吗?或者我是否遗漏了重要的一点?

【问题讨论】:

    标签: python mysql python-3.x pymysql


    【解决方案1】:

    当您运行 mysql 命令时,您是在 SSH shell 中执行此操作。也就是说,您正在通过localhost 连接连接到在远程机器上运行的服务器。该远程服务器似乎没有设置为允许对其进行远程连接,仅允许来自机器本身的连接。

    您需要让您的 python 脚本以与您相同的方式通过 SSH 连接到 MySQL 服务器。您可以在远程服务器上打开一个到端口 3306 的 SSH 隧道。

    我喜欢为此目的使用的模块是:https://pypi.python.org/pypi/sshtunnel

    from sshtunnel import SSHTunnelForwarder
    import pymysql
    
    server = SSHTunnelForwarder(
        'XXX.XXX.XXX.XXX',
        ssh_username='root',
        ssh_password='my_server_password',
        remote_bind_address=('127.0.0.1', 3306)
    )
    server.start()
    
    cnx = pymysql.connect(
        host='127.0.0.1',
        port=server.local_bind_port,
        user='root',
        password='my_database_password',
        db='my_database'
    )
    
    # Make sure to call server.stop() when you want to disconnect
    # after calling cnx.close()
    

    【讨论】:

    • 非常感谢!这个解决方案就像一个魅力。解释也很清楚。
    【解决方案2】:

    根据所提供的信息,我建议您尝试以下方法:

    1. 确保 MySQL 绑定地址为“0.0.0.0”。您可以通过编辑/etc/mysql/my.cnf 并检查bind-address 选项设置为“0.0.0.0”

    2. 来做到这一点
    3. 确保端口已从远程计算机打开。安装“nmap”然后使用nmap -sS -O -p3306 <public-server-ip>。如果看到类似3306/mysql open 的东西,一切都很好。如果没有,您需要确保您的防火墙没有阻止该端口。

    正如 Rocket Hazmat 建议的那样,您可能希望使用 SSH 隧道来降低直接暴露 MySQL 端口的风险,因为数据可能是以明文形式发送的。如果您只需要在部署到服务器之前在本地测试您的代码,您可以在运行 Python 代码之前使用以下命令:ssh -f user@serverip -L 3306:127.0.0.1:3306 -N。在这种情况下,您不需要完成第一步和第二步。

    【讨论】:

      【解决方案3】:

      工作代码

      #!/usr/local/bin/python3
      # -*- coding: utf-8 -*-
      
      import pymysql
      import sshtunnel
      from sshtunnel import SSHTunnelForwarder
      
      server = SSHTunnelForwarder(
          ('xx.xx.xx.xx', 22),
          ssh_username='deploy',
          ssh_pkey='~/.ssh/id_rsa',
          remote_bind_address=('127.0.0.1', 3306)
      )
      server.start()
      
      con = pymysql.connect(host='127.0.0.1', user='root', passwd='mysql', db='backoffice_demo', port=server.local_bind_port)
      
      with con:
      
          cur = con.cursor()
          cur.execute("SELECT VERSION()")
      
          version = cur.fetchone()
      
          print("Database version: {}".format(version[0]))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-02-13
        • 2013-03-06
        • 1970-01-01
        • 2014-10-04
        • 1970-01-01
        • 1970-01-01
        • 2015-01-22
        • 1970-01-01
        相关资源
        最近更新 更多