【问题标题】:How to connect to AWS RDS MySql database with Python如何使用 Python 连接到 AWS RDS MySql 数据库
【发布时间】:2020-10-18 23:06:44
【问题描述】:

我目前正在尝试使用 PyMySQL 库通过 python 程序连接到我在 AWS 上创建的 MySql 数据库

# !/usr/bin/env python
# -*- coding: utf-8 -*-
import pymysql

host = 'admin.cjp8hsqu4je0.us-east-2.rds.amazonaws.com'
user = 'admin'
password = '12345678'
database = 'admin'

connection = pymysql.connect(host, user, password, database)
with connection:
    cur = connection.cursor()
    cur.execute("SELECT VERSION()")
    version = cur.fetchone()
    print("Database version: {} ".format(version[0]))

当我运行上述代码时,出现以下错误:

Traceback (most recent call last):
  File "C:\Users\SuperPC\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pymysql\connections.py", line 581, in connect
    sock = socket.create_connection(
  File "C:\Users\SuperPC\AppData\Local\Programs\Python\Python38-32\lib\socket.py", line 808, in create_connection
    raise err
  File "C:\Users\SuperPC\AppData\Local\Programs\Python\Python38-32\lib\socket.py", line 796, in create_connection
    sock.connect(sa)
socket.timeout: timed out

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "bot.py", line 10, in <module>
    connection = pymysql.connect(host, user, password, database)
  File "C:\Users\SuperPC\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pymysql\__init__.py", line 94, in Connect
    return Connection(*args, **kwargs)
  File "C:\Users\SuperPC\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pymysql\connections.py", line 325, in __init__
    self.connect()
  File "C:\Users\SuperPC\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pymysql\connections.py", line 630, in connect
    raise exc
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'admin.cjp8hsqu4je0.us-east-2.rds.amazonaws.com' (timed out)")

我做错了什么?我给函数的参数是正确的。会不会是MySql驱动的问题?

【问题讨论】:

  • 您是否已将您的 RDS 设置为公开可用?您还可以显示您的 RDS 安全组吗?
  • "您是否已将您的 RDS 设置为公开可用?"可能不会,你能告诉我们怎么做吗? “您还可以显示您的 RDS 安全组吗?” VPC 安全组默认 (sg-09ddd998b30aa17c8) (active)
  • SG 的入站规则是什么?此外,目前还不清楚 RDS 是否公开可用。它是 RDS 设置中的一个选项。
  • 我会用截图给出答案,因为我无法将它粘贴到 cmets 中。

标签: mysql python-3.x amazon-web-services amazon-rds pymysql


【解决方案1】:

如果您想通过互联网从 AWS 外部访问您的 RDS,则应将其设置为公开

还应将其放置在公共子网(例如默认 VPC)中,并在其安全组中打开入站规则(良好做法限制访问 仅选择 IP 或 IP 范围,而不是使用 0.0.0.0/0):

希望这会有所帮助。

【讨论】:

  • 我也遇到了同样的错误。我遵循了上述所有步骤。我不知道出了什么问题。你能提出一个解决方案吗?
  • 我的要求是,我要连接RDS Aurora-mysql数据库,要创建表。
  • @siva 我认为对您的问题提出新问题会更好。
【解决方案2】:

此请求超时,表明您由于防火墙规则而无法连接。

如果您在 EC2 实例或容器上运行它,那么:

  • 确保将 RDS 实例配置为允许使用其安全组在端口 3306 上对实例/容器的任一子网范围进行入站访问。

如果您在外部运行它,那么您需要:

  • 通过 VPN 连接到您的 VPC 并更新 RDS 的安全组以将您的本地 CIDR 范围列入白名单
  • 如果您无法使用 VPN,则需要创建 RDS,以便通过安全组将入站访问列入您的公共 IP 地址的白名单公开访问。

如果您使用的是 Lambda,则应执行以下操作:

  • 将您的 Lambda 迁移到 VPC,将一个安全组附加到它以允许出站访问(默认情况下,它应该允许对所有内容的出站访问)。它应该位于私有子网中
  • 更新 RDS 数据库的安全组,以允许在端口 3306 上对 LAmbda 子网或附加到 Lambda 的安全组进行入站访问。

有关在 VPC 中配置 Lambda 的更多信息,请参见 this document

【讨论】:

    【解决方案3】:

    我终于得到了终极解决方案:

    如果您有一个正确连接到 RDS 实例的 EC2 实例,您可以在它们之间打开一个 ssh 隧道并使用 pymysql(python 库)。

    这里是拯救世界的神奇代码! (我添加了一些代码和cmets,但您可以使用下面的链接获取原始代码) LInk to the savior's github

    首先,安装这个库:

    • !pip 安装 sshtunnel

    • !pip 安装 PyMySQL

        # Import libraries
        from sshtunnel import SSHTunnelForwarder
        import pymysql
      
        # SSH (ec2_public_dns, ec2_user, pem_path, remote_bind_address=(rds_instance_access_point, port))
        with SSHTunnelForwarder(('ec2-52-202-194-76.public-ec2-instance.amazonaws.com'), ssh_username="ec2-user", ssh_pkey="~/ssh-tunnel-rds.pem", remote_bind_address=('private-rds-instance.ckfkidfytpr4.us-east-1.rds.amazonaws.com', 3306)) as tunnel:
            print("****SSH Tunnel Established****")
      
            db = pymysql.connect(
                host='127.0.0.1', user="rdsuser",password="rdspassword",
                port=tunnel.local_bind_port, database="dbName"
            )
            # Run sample query in the database to validate connection
            try:
                # Print all the databases
                with db.cursor() as cur:
                    # Print all the tables from the database
                    cur.execute('SHOW TABLES FROM dbName')
                    for r in cur:
                        print(r)
      
                    # Print all the data from the table
                    cur.execute('SELECT * FROM table_name')
                    for r in cur:
                        print(r)
            finally:
                db.close()
      
        print("YAYY!!")
      

    【讨论】:

      猜你喜欢
      • 2019-05-03
      • 2021-04-19
      • 2021-04-06
      • 2013-01-28
      • 1970-01-01
      • 1970-01-01
      • 2021-10-06
      • 2022-10-13
      • 2020-04-20
      相关资源
      最近更新 更多