Python 使用SQLAlchemy连接亚马逊极光

Python 使用SQLAlchemy连接亚马逊极光,python,sqlalchemy,amazon-aurora,Python,Sqlalchemy,Amazon Aurora,我正在尝试使用SSL连接通过SQLAlchemy连接到Amazon Aurora,并将IAM角色指定为数据库用户帐户,将身份验证令牌指定为密码,如[AWS文档]中所述 () 以下是我遵循的步骤 wget https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem export LIBMYSQL_ENABLE_CLEARTEXT_PLUGIN=1 aws rds generate-db-auth-token --hostn

我正在尝试使用SSL连接通过SQLAlchemy连接到Amazon Aurora,并将IAM角色指定为数据库用户帐户,将身份验证令牌指定为密码,如[AWS文档]中所述 ()

以下是我遵循的步骤

wget https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem

export LIBMYSQL_ENABLE_CLEARTEXT_PLUGIN=1

aws rds generate-db-auth-token --hostname 'datadbcluster-1.cluster-xxxxxxxxxxxx.us-west-2.rds.amazonaws.com' --port 3306 --username dt_analyst --region us-west-2 > /home/ubuntu/dt_analyst.pem

mysql -h datadbinstance2nd. xxxxxxxxxxxx.us-west-2.rds.amazonaws.com--ssl-ca /home/ubuntu/rds-combined-ca-bundle.pem -u dt_analyst --ssl-verify-server-cert --enable-cleartext-plugin -p'<token>'

我的答案有三:

IAM角色 这里没有提到一个步骤:您需要分配一个IAM角色,使您的客户端有权连接到RDS

对于“客户机”,我指的是任何AWS资源都在运行这个问题的代码。可以是lambda函数、EC2实例或其他。无论它是什么,它都有一个ARN,必须允许它执行操作
rds db:connect

URL引用连接字符串 然后可能存在RDS凭据问题。如果密码包含URL中不允许的字符,则您可能必须对其进行URL引用

  • Python3:
    passwd=urllib.parse.quote(rds\u密码)
  • Python2:
    passwd=urllib.quote(rds\u密码)
RDS临时凭据 最后,您的RDS数据库可能需要临时凭据。此代码示例显示了如何获取以下内容:

# get RDS config, often done through environment variables
import os

rds_host = os.environ.get("RDS_HOST")  
rds_port = os.environ.get("RDS_PORT")
rds_username = os.environ.get("RDS_USER")   

# get temp credential
import boto3

temp_passwd = boto3.client('rds').generate_db_auth_token(
    DBHostname=rds_host,
    Port=rds_port,
    DBUsername=rds_username 
)

rds_credentials = {'user': rds_username, 'passwd': temp_passwd}
把它放在一起: 我将user和passwd参数从连接字符串移动到
connect\u args
。这样就不需要URL引用了


另请参见:

我觉得您的交互很好,因此我建议为此联系AWS支持。如果你能弄明白,一定要分享!谢谢。代码片段包含一个遗漏:where
create\u engine
来自何处。我追踪到了
sqlalchemy.create_engine
,它将
connect_args
作为kwarg转发到底层的
PyMySQL
mysqlclient
连接器库。
# get RDS config, often done through environment variables
import os

rds_host = os.environ.get("RDS_HOST")  
rds_port = os.environ.get("RDS_PORT")
rds_username = os.environ.get("RDS_USER")   

# get temp credential
import boto3

temp_passwd = boto3.client('rds').generate_db_auth_token(
    DBHostname=rds_host,
    Port=rds_port,
    DBUsername=rds_username 
)

rds_credentials = {'user': rds_username, 'passwd': temp_passwd}
def create_sqlalchemy_engine(self):
    conn_str = f"{protocol}://{rds_host}:{rds_port}/{database}"

    kw = dict()
    kw.update(rds_credentials)
    # kw.update({'ssl': {'ca': /path/to/pem-file.pem}})  # MySQL
    # kw.update({'sslmode': 'verify-full', 'sslrootcert /path/to/pem-file.pem})  # PostgreSQL

    return create_engine(conn_str, connect_args=kw)