파이썬 - PostgreSQL의 with 문을 사용한 경우 연결 개체 누수
psycopg2를 이용하는 경우,
파이썬 - PostgreSQL 환경 구성
; https://www.sysnet.pe.kr/2/0/13077
다음과 같은 같이 코딩하면,
def test_postgre():
import psycopg2
with psycopg2.connect(...[생략]...) as db:
with db.cursor() as cursor:
sql = "SELECT * FROM TestTable"
cursor.execute(sql)
with로 사용한 db 연결 개체가 닫히지 않는 현상이 있습니다. 실제로 저 코드를 실행하는 웹 페이지를 방문한 후 PostgreSQL CLI를 통해
pg_stat_activity 테이블을 보면,
# /usr/bin/psql
psql (11.2 (Debian 11.2-1.pgdg90+1))
Type "help" for help.
root=# select client_addr, client_port from pg_stat_activity;
client_addr | client_port
----------------+-------------
192.168.100.50 | 33380
192.168.100.50 | 37612
192.168.100.50 | 59440
192.168.100.50 | 40936
192.168.100.50 | 48864
192.168.100.50 | 41622
192.168.100.50 | 47890
192.168.100.50 | 33652
| -1
172.17.0.1 | 41070
|
예제를 실행한 192.168.100.50 측에서의 연결 개체가 남아 있는 것을 볼 수 있습니다.
이에 대한 해답은 ^^;
How to Work with PostgreSQL in Python
; https://khashtamov.com/en/postgresql-with-python-and-psycopg2/
with와 함께 closing을 함께 써줘야 합니다.
def test_postgre():
import psycopg2
from contextlib import closing
with closing(psycopg2.connect(...[생략]...)) as db:
with db.cursor() as cursor:
sql = "SELECT * FROM TestTable"
cursor.execute(sql)
실제로 저렇게 처리한 후에는 pg_stat_activity가 조용해졌습니다. ^^
다른 db provider도 그런 식일까요? 일례로
제가 테스트한 mysql의 경우에는,
with MySQLdb.connect(...[생략]...) as conn:
conn.encoding = 'utf8'
with conn.cursor() as cursor:
query = "SELECT * FROM mytable;"
cursor.execute(query)
(closing 없이도) 연결 개체를 잘 정리합니다. 마찬가지로
pymysql도 with 구문이 적용됐습니다. 다른 예로는,
sqlite3의 경우 아예 지원이 안 되었죠! 이러한 처리가
dbapi2 명세에서 지정하지 않아 그런 것인지는 모르겠지만 암튼 with에 대한 처리를 할 때는 꼭 문서를 확인하든가, 직접 테스트를 해보는 것이 좋겠습니다. ^^;
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]