본문 바로가기

Programming Language/[Python]

[Python] sqlalchemy - text

728x90
반응형

sqlalchemy using text

python의 sqlalchemy 모듈을 사용해서 mariadb에 execute 할 때, delete 텍스트문이 실행되지 않는 문제가 발생했다.

이 문제의 원인과 해결법을 알아보자. 

 

처음에 실행한 코드는 다음과 같다.

import sqlalchemy as sa


# connect MariaDB
mariadb_user: str = config["datasource"]["user"]
mariadb_password: str = config["datasource"]["password"]
mariadb_host: str = config["datasource"]["host"]
mariadb_port: int = config["datasource"]["port"]
mariadb_dbname: str = config["datasource"]["database"]
sa_conn_str: str = (
    f"mysql+pymysql://{mariadb_user}:{mariadb_password}@{mariadb_host}:{mariadb_port}/{mariadb_dbname}"
    f"?charset=utf8mb4"
)
sa_engine = sa.create_engine(sa_conn_str)
sa_conn = sa_engine.connect()

sql: str = f"DELETE FROM <table_name> WHERE date_time = '{target_date_formatted_utc}'"

sa_conn.execute(sa.text(sql))

 

1차 시도

실행1. sqlalchemy engine으로 execute할 때 execution_options()의 옵션 중 autocommit을 True로 지정하기

출처: https://stackoverflow.com/questions/17972020/how-to-execute-raw-sql-in-flask-sqlalchemy-app

result = db.engine.execute(text("<sql here>").execution_options(autocommit=True))

실행 결과:

sa_engine.execute(sa.text(sql)).execution_options(autocommit=True)
# engine.execute(text(sql).execution_options(autocommit=True))  # 예시

# 에러문
# Traceback (most recent call last):
# ...
#     sa_engine.execute(sa.text(sql)).execution_options(autocommit=True)
# AttributeError: 'Engine' object has no attribute 'execute'

 

2차 시도

sqlalchemy engine에 execution_options()를 사용해서 autocommit으로 지정해서 engine을 덮어쓰기

 

출처: SQLAlchemy2.0 Documentation - Mainataining Multiple Isolation Levels for a Single Engine

from sqlalchemy import create_engine

eng = create_engine("postgresql+psycopg2://scott:tiger@localhost/test")

autocommit_engine = eng.execution_options(isolation_level="AUTOCOMMIT")

성공.

 

최종 코드:

import sqlalchemy as sa


# connect MariaDB
mariadb_user: str = config["datasource"]["user"]
mariadb_password: str = config["datasource"]["password"]
mariadb_host: str = config["datasource"]["host"]
mariadb_port: int = config["datasource"]["port"]
mariadb_dbname: str = config["datasource"]["database"]
sa_conn_str: str = (
    f"mysql+pymysql://{mariadb_user}:{mariadb_password}@{mariadb_host}:{mariadb_port}/{mariadb_dbname}"
    f"?charset=utf8mb4"
)
sa_engine = sa.create_engine(sa_conn_str)
sa_engine = sa_engine.execution_options(isolation_level="AUTOCOMMIT")
sa_conn = sa_engine.connect()

sql: str = f"DELETE FROM <table_name> WHERE date_time = '{target_date_formatted_utc}'"

sa_conn.execute(sa.text(sql))

sqlalchemy engine의 execution_option을 지정한 뒤 engine에 connect하면서 해결했다.

아직 미스터리인 점은 이 옵션값을 주지 않아도 다른 서버에선 동작을 했던 코드가 이 서버에선 동작하지 않는다는 점이다.

서버에 설치된 모듈 버전 차이나 sqlalchemy session 차이 등 정확한 원인을 찾게 되면 이 페이지로 돌아와야겠다.

 


Reference

반응형

'Programming Language > [Python]' 카테고리의 다른 글

[Python] pymysql connection option  (0) 2023.06.21
[Python] Jinja template  (0) 2023.04.30
[Python] datetime format  (0) 2023.04.18
[Python] Redis connection  (0) 2023.04.15
[Python] PID 의미  (0) 2023.04.15