使用
PyMySQL
,我得到 pymysql.err.OperationalError: (1045, u"Access denied for user 'my_user'@'<MY_IP_ADDRESS>' (using password: YES)")
,但是,我可以在本机上使用相同的凭据从命令行或 MySQL Workbench 登录。而且,我可以使用 PyMySQL 连接到 localhost
。这是我的示例测试代码:
import pymysql
prod_conn = pymysql.connect(
host='correct-host-name.us-west-2.rds.amazonaws.com',
user='my_user',
password='correct_password',
port=3306,
database='my_db')
但是,在同一台机器上从命令行使用
mysql -hcorrect-host-name.us-west-2.rds.amazonaws.com -umy_user -pcorrect_password -P3306 -Dmy_db
,我就可以正常进入了。
谷歌搜索后,我尝试检查用户的授权,我相信用户设置正确。
SHOW GRANTS FOR CURRENT_USER()
回归
Grants for my_user@%
'GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, PROCESS, REFERENCES, INDEX, ALTER, SHOW DATABASES, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER ON *.* TO \'my_user\'@\'%\' WITH GRANT OPTION'
我尝试检查
SELECT USER(), CURRENT_USER();
并返回
USER() CURRENT_USER()
'my_user@<MY_IP_ADDRESS>' 'my_user@%'
因此,用户似乎设置正确,我对此表示怀疑,因为我可以通过其他选项进行连接。我还尝试了 https://forums.aws.amazon.com/thread.jspa?messageID=707103 的两个建议(具体来说,使用不同的参数组和
log_bin_trust_function_creators == 1
并使用不带标点符号的密码),但均无济于事。
我想在 lambda 函数中使用它,所以我真的想使用 PyMySQL 来使其成为仅 Python 的解决方案,而不是尝试 MySQLDB 或其他库。
审核后我认为没有匿名用户
SELECT user,host FROM mysql.user;
user host
'my_user' '%'
'mysql.sys' 'localhost'
'rdsadmin' 'localhost'
感谢该社区可能对如何继续进行的任何其他想法......
我通过创建一个新用户解决了这个问题。我只需要该用户的读取权限,因此这是比使用具有如此高权限的默认用户更好的方法。我仍然不确定为什么原来的不起作用,但最终起作用的是:
# Grants for my_new_user@%
'GRANT SELECT ON *.* TO \'my_new_user\'@\'%\''
对于任何想要使用
sqlalchemy
+ pymysql
连接的人。作为奖励,我包含了使 IAM AUthentication
工作所需的设置。此设置适合我在 Lambda 函数中使用角色。
DBHostname = DBCLUSTER_HOSTNAME
DBPort = DBCLUSTER_PORT
DBUsername = DBCLUSTER_USER
DBName = DBCLUSTER_NAME
engine = sqlalchemy.create_engine(
"mysql+pymysql:///"
) # connection params will be set by the event callback
@sqlalchemy.event.listens_for(engine, "do_connect")
def provide_token(dialect, conn_rec, cargs, cparams):
# Token is for IAM auth
client = boto3.client("rds")
token = client.generate_db_auth_token(
DBHostname=DBHostname,
Port=int(DBPort),
DBUsername=DBUsername,
Region=REGION,
)
# set up db connection parameters, alternatively we can get these from boto3 describe_db_instances
cparams["host"] = DBHostname
cparams["port"] = int(DBPort)
cparams["user"] = DBUsername
cparams["password"] = token # If not IAM Auth, just put password here
cparams["database"] = DBName
# Parameters needed for IAM Auth
cparams["ssl"] = {
"ca": "ssl-ca-bundle.pem",
"verify_identity": False,
}
cparams["auth_plugin_map"] = {
"mysql_clear_password": None,
}