Confusing behavior when using % in password in sqlalchemy.url inside alembic.ini #1662
Replies: 3 comments 1 reply
-
By the way this way works:
There are no unshielded characters used here, why there are such conflicts and SQLAlchemy and Alembic can't read the same data in the same way, it's strange, I could be wrong and I'm waiting for your answer. |
Beta Was this translation helpful? Give feedback.
-
Alembic uses Python's ConfigParser. This configparser interpolates percent signs, which Alembic uses to support the token
So this is just the percent sign. From there it looks like you're already familiar with escaping the @ signs in the URL string itself Here's a program that will run any URL through the same steps as alembic + SQLAlchemy's unescaping of percent signs, illustrating your URL including an @ sign by first URL escaping it as from configparser import ConfigParser
import urllib.parse
MY_URL = "postgresql+psycopg2://postgreSS:P%%40ssw0rd@10.163.1.64:5432/auth_db"
config = f"""
[section]
sqlalchemy.url = {MY_URL}
"""
pp = ConfigParser()
pp.read_string(config)
url_from_configparser = pp.get("section", "sqlalchemy.url")
print(f"Retreived from configparser: {url_from_configparser}")
unescaped_url = urllib.parse.unquote(url_from_configparser)
print(f"Will be unescaped by SQLAlchemy as: {unescaped_url}")
from sqlalchemy import make_url
assert make_url(url_from_configparser).password == "P@ssw0rd"
print(
f"SQLAlchemy parsed the password as: {make_url(url_from_configparser).password}"
)
That's Python code that is bypassing the use of Here's another program that uses the same functions to go the other way. Put your actual password into it and it will run these two escaping sequences: import urllib.parse
MY_PASSWORD = "P@ssw0rd"
escaped_password = urllib.parse.quote(MY_PASSWORD)
print(f"Password to send to make_url: {escaped_password}")
percent_escaped_password = escaped_password.replace("%", "%%")
print(f"Password to apply in interpolated config file: {percent_escaped_password}") |
Beta Was this translation helpful? Give feedback.
-
I've added a detailed section to Alembic's documentation with the above details at https://alembic.sqlalchemy.org/en/latest/tutorial.html#escaping-characters-in-ini-files |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
I'm having issues connecting to my PostgreSQL database using Alembic, specifically due to a
@
character in the database password. When using a URL like this inalembic.ini
:sqlalchemy.url = postgresql+psycopg2://postgreSS:P%40ssw0rd@10.163.1.64:5432/auth_db
I get the following error:
configparser.InterpolationSyntaxError: '%' must be followed by '%' or '(', found: '%40ssw0rd@...'
When I try to escape
%
like this:sqlalchemy.url = postgresql+psycopg2://postgreSS:P%%ssw0rd@10.163.1.64:5432/auth_db
I then get a database connection error:
sqlalchemy.exc.OperationalError: ... password authentication failed for user "postgreSS"
What works
The same URL does work perfectly when passed directly to create_engine() from sqlalchemy in my FastAPI application.
create_engine("postgresql+psycopg2://postgreSS:P%40ssw0rd@10.163.1.64:5432/auth_db")
Questions
Beta Was this translation helpful? Give feedback.
All reactions