如何使用 Python 连接到 AWS RDS MySql 数据库

Posted

技术标签:

【中文标题】如何使用 Python 连接到 AWS RDS MySql 数据库【英文标题】:How to connect to AWS RDS MySql database with Python 【发布时间】: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 中。 【参考方案1】:

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

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

希望这会有所帮助。

【讨论】:

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

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

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

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

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

通过 *** 连接到您的 VPC 并更新 RDS 的安全组以将您的本地 CIDR 范围列入白名单 如果您无法使用 ***,则需要创建 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!!")

【讨论】:

以上是关于如何使用 Python 连接到 AWS RDS MySql 数据库的主要内容,如果未能解决你的问题,请参考以下文章

如何从本地使用 SSL 加密连接到 AWS RDS?

无法通过 Python Elastic Beanstalk 中的 Flask SQLAlchemy URI 连接到 AWS MySQL RDS 实例

使用 AWS Lambda 连接到 Oracle RDS 时出现错误 (DPI-1047)

如何将 AWS ELB 连接到运行 MS SQL 的 RDS?

AWS:如何将 *** 客户端连接到 RDS(*** 服务器 EC2 和 RDS 在同一个 VPC 中)

无法通过 AWS.RDS.Signer 连接到 RDS