티스토리 뷰

반응형

airflow.cfg 의 dbms 연결설정의 경우 아래와 같은 패턴으로 입력을 해야하는데, 문제는 암호에 @ 가 존재해서 도메인을 잘못 판단하는 문제가 발생했다. 구글링 해보면 python 코드를 통해 해결하거나, "@" 를 "%40" 형태로 치환하면 된다고 하는데, 그렇게 해결이 안되었다. 그 문제는 configparser 에서 "%" 가 또 영향을 받기 때문이었다.

sql_alchemy_conn = mysql+mysqldb://<아이디>:<암호>@<도메인>:<포트>/airflow_db?charset=utf8

해결방법

결론부터 말하면 @ 는 %%40 으로 대체해야 설정이 정상적으로 인지된다. 

urllib 의 quote 로 변환한 결과가 %40 인데, configparser 에서는 또 % 를 추가로 이스케입해줘야 하는 문제가 있기 때문이다.

즉, "pass@word" 라는 암호는 "pass%%40word"  로 이스케입처리하면 문제없이 동작된다.

 

파이썬 코드로 설명하면 아래와 같다.

from urllib import parse
PASSWORD = 'pass@word'
print(  parse.quote(PASSWORD).replace('%', '%%') ) 
# 결과 - pass%%40word

즉, 예를 들면 아래와 같다.

# 오류나는 표현 (escape 이전)
# sql_alchemy_conn = mysql+mysqldb://airflow_user:pass@word@myhome.com:3306/airflow_db?charset=utf8

# 잘동작하는 표현 (escape 이후)
sql_alchemy_conn = mysql+mysqldb://airflow_user:pass%%40word@myhome.com:3306/airflow_db?charset=utf8

 

에러메시지

예를 들어서, 패스워드가 "pass@word" 였을때,  잘못 파싱되어서 암호를 pass 로 인지하고, 뒤쪽 word와 도메인정보가 합쳐지는 형태로 정보를 잘못 파악해서 이런 문제가 발생되는현상이다.

(py3) -bash-4.2$ airflow scheduler -D
[2023-04-12 19:44:00,523] {settings.py:260} DEBUG - Setting up DB connection pool (PID 62830)
[2023-04-12 19:44:00,524] {settings.py:362} DEBUG - settings.prepare_engine_args(): Using pool settings. pool_size=5, max_overflow=10, pool_recycle=1800, pid=62830
[2023-04-12 19:44:00,540] {cli_action_loggers.py:40} DEBUG - Adding <function default_action_log at 0x7f35844a11f0> to pre execution callback
[2023-04-12 19:44:00,811] {cli_action_loggers.py:66} DEBUG - Calling callbacks: [<function default_action_log at 0x7f35844a11f0>]
[2023-04-12 19:44:00,814] {cli_action_loggers.py:105} WARNING - Failed to log action with (MySQLdb.OperationalError) (2005, "Unknown MySQL server host 'word@myhostname' (2)")
(Background on this error at: https://sqlalche.me/e/14/e3q8)
[2023-04-12 19:44:00,886] {cli_action_loggers.py:84} DEBUG - Calling callbacks: []
Traceback (most recent call last):
  File "/home/gildong/airflow/py3/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 3243, in _wrap_pool_connect
    return fn()
  File "/home/gildong/airflow/py3/lib/python3.9/site-packages/sqlalchemy/pool/base.py", line 310, in connect
    return _ConnectionFairy._checkout(self)
  File "/home/gildong/airflow/py3/lib/python3.9/site-packages/sqlalchemy/pool/base.py", line 868, in _checkout
    fairy = _ConnectionRecord.checkout(pool)
  File "/home/gildong/airflow/py3/lib/python3.9/site-packages/sqlalchemy/pool/base.py", line 476, in checkout
...생략...
  File "/home/gildong/airflow/py3/lib/python3.9/site-packages/MySQLdb/__init__.py", line 123, in Connect
    return Connection(*args, **kwargs)
  File "/home/gildong/airflow/py3/lib/python3.9/site-packages/MySQLdb/connections.py", line 185, in __init__
    super().__init__(*args, **kwargs2)
sqlalchemy.exc.OperationalError: (MySQLdb.OperationalError) (2005, "Unknown MySQL server host 'word@myhostname' (2)")
(Background on this error at: https://sqlalche.me/e/14/e3q8)
[2023-04-12 19:44:00,892] {settings.py:398} DEBUG - Disposing DB connection pool (PID 62830)

만약, @ 를 단순히 %40 으로 변경하면 아래와 같은 오류메시지가 출력될것이다.

  File "/home/gildong/airflow/py3/lib/python3.9/site-packages/airflow/configuration.py", line 532, in get
    option = self._get_option_from_config_file(deprecated_key, deprecated_section, key, kwargs, section)
  File "/home/gildong/airflow/py3/lib/python3.9/site-packages/airflow/configuration.py", line 596, in _get_option_from_config_file
    return expand_env_var(super().get(section, key, **kwargs))
  File "/opt/local/python39/lib/python3.9/configparser.py", line 799, in get
    return self._interpolation.before_get(self, section, option, value,
  File "/opt/local/python39/lib/python3.9/configparser.py", line 395, in before_get
    self._interpolate_some(parser, option, L, value, section, defaults, 1)
  File "/opt/local/python39/lib/python3.9/configparser.py", line 442, in _interpolate_some
    raise InterpolationSyntaxError(
configparser.InterpolationSyntaxError: '%' must be followed by '%' or '(', found: '%40word@MYHOST:3306/airflow_db?charset=utf8'

이 문제를 해결하기위해 찾아보면 sqlalchemy 의 create_engine 에 이스케입 혹은 코드로 대응하는것만 나오고 한참 헤맸는데 삽질끝에 답을 찾아서 한숨 돌린것 같다.

 

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함