事象の説明
sqlalchemy を使って DB に接続する際に次のような方法で engine を生成します。
username = 'pyuser'
password = 'Pyp@ssw0rd'
host = 'localhost'
port = 3306
database = 'pytest'
charset_type = 'utf8'
connection_url=f"mysql://{username}:{password}@{host}:{port}/{database}?charset={charset_type}"
engine = create_engine(connection_url)
ここではデータベースとして MySQL を使っています。この engine を用いて DB に接続してクエリを実行すると以下のように怒られます。
session = sessionmaker(bind=engine)()
session.execute("SELECT 1;")
sqlalchemy.exc.OperationalError: (MySQLdb._exceptions.OperationalError) (2005, "Unknown MySQL server host 'ssw0rd@localhost' (11)")
DBに接続するためのURLをよく見ると、パスワードとホスト名の区切り文字が @
となっています。上の例ではパスワードに @
が含まれており、最初に現れたパスワード内の @ が区切り文字と判断されてしまったことがエラーの原因でした。
対応方法
sqlalchemy には URL class が用意されているので、こちらを使うとよいです。
from sqlalchemy.engine.url import URL
connection_url = URL.create(
drivername="mysql",
username=username,
password=password,
host=host,
port=port,
database=database,
query = {"charset": charset_type},
)
print(connection_url)
結果
mysql://pyuser:Pyp%40ssw0rd@localhost:3306/pytest?charset=utf8
上記結果からもわかるように、パスワードに含まれている @
が単に URL encode されているだけですね。