Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从python连接到远程服务器中的MySQL_Python_Mysql_Python 3.x_Pymysql - Fatal编程技术网

从python连接到远程服务器中的MySQL

从python连接到远程服务器中的MySQL,python,mysql,python-3.x,pymysql,Python,Mysql,Python 3.x,Pymysql,我在MacOS X 10.12上使用Python3.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 它可以工作,我可以用我的数据库

我在MacOS X 10.12上使用Python3.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)")
凭据是正确的凭据,我已经检查了端口是否是正确的端口,正如其他文章中所建议的那样。我怀疑这可能与数据库也有密码有关,不仅仅是服务器,但我还没有找到任何方法将这两个密码都包括在内。事实上,我不确定connect命令中应该包含哪个密码,如果是服务器密码还是数据库密码。这对他们两个都不起作用


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

当您运行
mysql
命令时,您是在SSH shell中执行此操作的。也就是说,您正在通过
localhost
连接连接到远程计算机上运行的服务器。远程服务器似乎不允许远程连接到它,只允许来自机器本身的连接

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

为此,我想使用的模块是:


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

  • 确保MySQL绑定地址为“0.0.0.0”。您可以通过编辑
    /etc/mysql/my.cnf
    并选中
    绑定地址
    选项设置为“0.0.0.0”来完成此操作

  • 确保端口已从远程计算机打开。安装“nmap”,然后使用
    nmap-sS-O-p3306
    。如果看到类似于
    3306/mysql open的东西
    都很好。如果没有,您需要确保防火墙没有阻塞该端口

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

    工作代码

    #!/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]))
    

    非常感谢你!这个解决办法很有效。解释也很清楚。
    #!/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]))