2024. 8. 20. 15:20ㆍProgramming/python
Mysql 8.0 으로 업그레이드를 진행하면서, default 값으로 사용하던 collation과 useSSL을 명시적으로 선언해야 할 필요가 있었다.
그래서 아래와 같은 요청을 받게 되었다.
jdbc:mysql://localhost:3306/schema?connectionCollation=utf8mb4_unicode_ci&useSSL=false
나의 경우 SQLAlchemy + pyMySQL을 사용하고 있었기 때문에 아래와 같이 db url을 수정하고 테스트를 진행했다.
mysql+pymysql://localhost:3306/schema?connectionCollation=utf8mb4_unicode_ci&useSSL=false
하지만 아래와 같은 에러가 발생!!
unexpected keyword argument 'connectionCollation'
그래서 pyMysql에서는 어떻게 collation을 적용해야 하나 구글링하기 시작했고 결국 아래와 같은 해답을 얻었다.
connect_args = {'init_command':"SET @@collation_connection='utf8mb4_unicode_ci'"}
with sqlalchemy.create_engine(url, connect_args=connect_args).connect()
이렇게 수정 후 테스트를 진행했으나 다시 아래와 같은 에러가 발생!
InternalError: (pymysql.err.InternalError) (1193, u'Unknown system variable 'tx_isolation')
와.... 도저히 모르겠는..... db 팀에 문의를 넣었더니.. SQLAlchemy 버전을 1.2.0 이상으로 올리라고 조언을 줌..
올리고 나니 정상 동작 완료!! 하지만 아래와 같은 에러가 또 발생!!
unexpected keyword argument 'useSSL'
이번에도 열심히 구글링!!
아래의 링크를 참조하여 ssl_mode, ssl_disabled 등의 파라미터 값을 사용해봤으나 동일하게 예상하지 못한 키워드 argument라는 에러가 발생한다.
https://dev.mysql.com/doc/connector-python/en/connector-python-connectargs.html
일단 원인을 파악해야 해서 내가 깔린 버전의 pyMysql 패키지의 코드를 들여다 보기로 함.(0.7.0)
site_packages/pymysql 폴더로 들어간 후 connections.py 코드를 연 후 아래와 같은 내용을 확인했다.
def __init__(self, host=None, user=None, password="",
database=None, port=3306, unix_socket=None,
charset='', sql_mode=None,
read_default_file=None, conv=decoders, use_unicode=None,
client_flag=0, cursorclass=Cursor, init_command=None,
connect_timeout=None, ssl=None, read_default_group=None,
compress=None, named_pipe=None, no_delay=None,
autocommit=False, db=None, passwd=None, local_infile=False,
max_allowed_packet=16*1024*1024, defer_connect=False,
auth_plugin_map={})
init 함수를 보니 ssl_mode, ssl_disabled 등의 argument는 설정이 안되어 있었고, 이로 인해 에러가 발생하는 걸 확인할 수 있었다. 그럼 이제 코드를 다시 확인해보며 어떻게 해야 ssl을 disable 할 수 있는지를 확인하자. 코드를 보다보니 아래와 같이 ssl 설정 부분을 확인!!
self.ssl = False
if ssl:
if not SSL_ENABLED:
raise NotImplementedError("ssl module not found")
self.ssl = True
client_flag |= CLIENT.SSL
self.ctx = self._create_ssl_ctx(ssl)
기본적으로 self.ssl은 False로 설정이 되어 있고, ssl 값을 파라미터로 받아서 해당 값이 있는 경우에만 self.ssl을 True로 바꾸고 ssl_context를 생성하는 걸 확인할 수 있다. 그리고 ssl 값은 따로 설정 값을 안주면 기본적으로 None으로 설정되게 되어 있다.
결론적으로 db 연결 시 ssl 과 관련해서 어떤 설정을 하지 않아도 기본적으로 self.ssl = False가 유지되도록 설정이 되어 있다.