Python3.10.6下Alembic连接含特殊字符的PostgreSQL密码遇插值语法错误
解决Alembic处理含特殊字符密码时的插值语法错误
问题背景
使用Python 3.10.6 + Alembic操作PostgreSQL,密码包含@和$特殊字符。已在migrations/env.py中对密码做URL编码,alembic.ini通过占位符拼接连接串,但执行命令pipenv run alembic revision --autogenerate -m "Initial migration"时触发错误:
ValueError: invalid interpolation syntax in 'P%40%24%24w0rd' at position 1
错误原因
URL编码后的密码包含%符号(比如@编码为%40,$编码为%24),而alembic.ini中使用的%(DB_PASSWORD)s是ConfigParser的插值语法,它会将字符串中的%识别为插值标记,导致把%40误判为无效的插值语法,从而抛出错误。
解决方案
方案1:直接在env.py中构造完整数据库URL(推荐)
绕过alembic.ini的占位符拼接,直接在migrations/env.py中生成编码后的完整连接串并设置到配置中:
修改migrations/env.py:
import urllib.parse import json from alembic import context f = open("/etc/config.json", "r") json_config = json.load(f) config = context.config # 编码密码并构造完整URL db_user = json_config["DB_USERNAME"] db_password = urllib.parse.quote_plus(json_config["DB_PASSWORD"]) db_host = json_config["DB_HOST"] db_database = json_config["DB_DATABASE"] full_db_url = f"postgresql://{db_user}:{db_password}@{db_host}/{db_database}" # 直接设置sqlalchemy.url配置项 config.set_main_option("sqlalchemy.url", full_db_url)
此时alembic.ini中的sqlalchemy.url可以保留任意占位值(比如sqlalchemy.url = placeholder),因为env.py中的设置会覆盖它。
方案2:转义编码密码中的%符号
如果要保留alembic.ini的占位符拼接逻辑,需要将编码后的密码中的%转义为%%(ConfigParser中用%%表示单个普通%):
修改migrations/env.py中设置密码的行:
encoded_password = urllib.parse.quote_plus(json_config["DB_PASSWORD"]) # 将%转义为%%,避免ConfigParser插值错误 config.set_section_option(section, "DB_PASSWORD", encoded_password.replace("%", "%%"))
alembic.ini的配置保持不变:
sqlalchemy.url = postgresql://%(DB_USERNAME)s:%(DB_PASSWORD)s@%(DB_HOST)s/%(DB_DATABASE)s
内容的提问来源于stack exchange,提问作者khteh
相关产品推荐
相关产品推荐

