简体   繁体   English

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

[英]How to connect to AWS RDS MySql database with Python

I am currently trying to connect to my MySql database created on AWS with a python program using the library PyMySQL我目前正在尝试使用库 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]))

When I run the above code I get the following error:当我运行上面的代码时,我收到以下错误:

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)")

What am I doing wrong?我究竟做错了什么? The arguments I gave to the function are correct.我给 function 的 arguments 是正确的。 Could it be a problem with the MySql driver? MySql 驱动程序有问题吗?

If you want to access your RDS from outside of AWS over internet, than it should be set to be publicly available :如果您想通过 Internet 从 AWS 外部访问您的 RDS,则应将其设置为公开可用

在此处输入图像描述

Also it should be placed in a public subnet (eg default VPC) and have opened inbound rules in its security group ( good practice is to limit access to only selected IPs or IP range, rather then using 0.0.0.0/0 ):此外,它应该放置在公共子网(例如默认 VPC)中,并在其安全组中打开入站规则(好的做法限制对选定 IP 或 IP 范围的访问,而不是使用0.0.0.0/0 ):

在此处输入图像描述

Hope this helps.希望这可以帮助。

This request timed out which indicates that you are unable to connect due to a firewall rule.此请求超时,这表明您由于防火墙规则而无法连接。

If you are running this on an EC2 instance or container then:如果您在 EC2 实例或容器上运行它,那么:

  • Ensure that the RDS instance is configured to allow inbound access to either the subnet range for the instance/container on port 3306 using its security group.确保将 RDS 实例配置为允许使用其安全组在端口 3306 上对实例/容器的任一子网范围进行入站访问。

If you are running this externally then either you will need to:如果您在外部运行它,那么您将需要:

  • Connect via a VPN to your VPC and update the security group of RDS to whitelist your on-premise CIDR range通过 VPN 连接到您的 VPC 并更新 RDS 的安全组以将您的本地 CIDR 范围列入白名单
  • If you cannot use a VPN the RDS will need to be created to be publicly accessible with a security group whitelisting inbound access to your public IP address.如果您无法使用 VPN,则需要创建 RDS 以公开访问,并使用安全组将入站访问列入您的公共 IP 地址的白名单。

If you are using a Lambda the following should be done:如果您使用的是 Lambda,则应执行以下操作:

  • Migrate your Lambda into the VPC, attach a security group to it allowing outbound access (by default it should allow outbound access to everything).将您的 Lambda 迁移到 VPC,将安全组附加到它以允许出站访问(默认情况下,它应该允许对所有内容的出站访问)。 It should sit in private subnets它应该位于私有子网中
  • Update the security group of the RDS database to allow inbound access on port 3306 to either the LAmbda subnets or the security group attached to the Lambda.更新 RDS 数据库的安全组以允许在端口 3306 上对 LAmbda 子网或附加到 Lambda 的安全组进行入站访问。

More information on configuring the Lambda within a VPC is in this document .有关在 VPC 中配置 Lambda 的更多信息,请参阅本文档

Finally I get the ultimate solution:最后我得到了最终的解决方案:

If you have an EC2 instance that is properly connected to the RDS instance, you can open a ssh tunnel between them and use pymysql (python library).如果您有一个正确连接到 RDS 实例的 EC2 实例,您可以在它们之间打开 ssh 隧道并使用 pymysql(python 库)。

Here is the amazing code that saves the day, (I add some code and comments, but you can get the original code using the link below) LInk to the savior's github这是拯救一天的神奇代码,(我添加了一些代码和注释,但您可以使用下面的链接获取原始代码)链接到救世主的 github

First of all, install this libraries:首先,安装这个库:

  • !pip install sshtunnel !pip 安装 sshtunnel

  • !pip install PyMySQL !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!!")

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

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