SQLAlchemy 에서 비밀번호 특수문자 문제 해결
1. Intro
Python에서 SQLAlchemy나 다른 DB 라이브러리를 사용해 데이터베이스에 연결할 때, 가끔 예상치 못한 연결 오류가 발생할 수 있습니다.
그 중 자주 만날 수 있는 문제가 바로 DB 비밀번호에 특수문자가 포함된 경우입니다. 예를 들어 아래와 같은 DB 접속 정보가 있다고 가정해보겠습니다.
1
2
3
4
5
host = "x.y.z.q"
port = "3306"
user = "db_user"
pw = "abc123!@#"
db = "example"
이 정보를 바탕으로 DB URL을 만들면 보통 다음과 같은 형태가 됩니다.
1
db_url = "mysql+pymysql://db_user:abc123!@#@x.y.z.q:3306/example"
겉보기에는 문제가 없어 보이지만, 실제로는 이 URL이 올바르게 해석되지 않을 수 있습니다.
DB 연결 URL에서 @ 문자는 사용자 인증 정보와 호스트를 구분하는 역할을 합니다. 그런데 비밀번호 안에도 @ 문자가 포함되어 있기 때문에, SQLAlchemy나 DB 드라이버가 URL을 해석하는 과정에서 혼란이 생길 수 있습니다. 따라서 아래처럼 사용자의 의도와 URL 파서의 해석이 엇갈리게 됩니다.
1
2
3
4
5
6
7
# 사용자 의도
pw = "abc123!@#"
host = "x.y.z.q
# URL 파서 : 아..! password 와 host 는 아래와 같구나..?!
pw = "abc123!"
host = "#@x.y.z.q"
결과적으로 잘못된 호스트 정보로 접속을 시도하게 되고, DB 연결은 실패합니다. 그렇다면 비밀번호에 특수문자가 포함되어 있을 때는 어떻게 처리해야 할까요?
2. quote_plus
이 문제는 비밀번호를 URL 인코딩하면 해결할 수 있습니다.
quote_plus 는 urllib.parse 모듈 하위의 함수로, 이는 문자열 안의 특수문자를 URL에서 안전하게 사용할 수 있는 형태로 변환해, 특수문자를 오해하는 일을 방지합니다.
사용법은 간단합니다. 해당 함수에 인코딩할 문자열을 넣어주기만 하면 됩니다.
1
2
3
4
5
from urllib.parse import quote_plus
pw = "abc123!@#"
encoded_pw = quote_plus(pw)
print(f"인코딩된 비밀번호 : {encoded_pw}")
실행 결과는 다음과 같습니다.
1
인코딩된 비밀번호 : abc123%21%40%23
특수문자가 아래와 같이 치환된 것을 알 수 있습니다.
1
2
3
! -> %21
@ -> %40
# -> %23
3. 인코딩된 비밀번호로 DB URL 만들기
이제 인코딩된 비밀번호로 DB URL 을 만들어보겠습니다.
1
2
3
4
5
6
7
8
9
10
from urllib.parse import quote_plus as qp
host = "x.y.z.q"
port = "3306"
user = "db_user"
pw = "abc123!@#"
db = "example"
db_url = f"mysql+pymysql://{user}:{qp(pw)}@{host}:{port}/{db}"
print(db_url)
실행 결과는 아래와 같습니다.
1
mysql+pymysql://db_user:abc123%21%40%23@x.y.z.q:3306/example
Comments