Passing the DB URL through config.set_main_option() runs it through
ConfigParser, which treats '%' as interpolation syntax — so any password
character that URL-encodes to %xx ('!', '@', '#', ...) crashed migrations
('invalid interpolation syntax'). Build the engine directly from the URL
instead of routing it through the ini config.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>