使用环境变量配置Alembic时,含特殊字符的数据库密码优化处理咨询
处理Alembic数据库密码含特殊字符的简便方案
方法1:用SQLAlchemy URL构造器(推荐)
SQLAlchemy自带的URL.create()会自动处理密码中的特殊字符编码,不用手动调用quote_plus,逻辑更可靠。生成URL后只需转义%(因为Alembic配置会把%当作占位符解析):
from sqlalchemy.engine import URL # 构造URL对象 db_url = URL.create( drivername="postgres+psycopg2", username=settings.db_user, password=settings.db_password, host=settings.db_host, port=settings.db_port, database=settings.db_name ) # 转义%后传入Alembic配置 config.set_main_option("sqlalchemy.url", str(db_url).replace("%", "%%"))
方法2:直接在env.py中构造引擎
如果不想通过Alembic的sqlalchemy.url配置,可直接在env.py里用URL.create()生成URL并创建引擎,跳过Alembic配置的字符串解析,也就不用处理%转义:
# env.py中替换原有获取URL的逻辑 from sqlalchemy.engine import URL from my_app.config import settings def run_migrations_offline(): url = URL.create( drivername="postgres+psycopg2", username=settings.db_user, password=settings.db_password, host=settings.db_host, port=settings.db_port, database=settings.db_name ) context.configure( url=url, target_metadata=target_metadata, literal_binds=True, dialect_opts={"paramstyle": "named"}, ) with context.begin_transaction(): context.run_migrations() def run_migrations_online(): connectable = create_engine( URL.create( drivername="postgres+psycopg2", username=settings.db_user, password=settings.db_password, host=settings.db_host, port=settings.db_port, database=settings.db_name ) ) with connectable.connect() as connection: context.configure( connection=connection, target_metadata=target_metadata ) with context.begin_transaction(): context.run_migrations()
补充说明
你之前的方法需要替换%是因为Alembic的配置系统会将%识别为配置变量的占位符(比如%(db_user)s),所以编码后的%2F这类字符会被错误解析,必须转义为%%。而用URL.create()的好处是它会严格按照URL编码规范处理特殊字符,比手动调用quote_plus更不易出错。
内容的提问来源于stack exchange,提问作者Ivy Kutswa
相关产品推荐
相关产品推荐

