오지's blog

pymysql.err.Error: Already closed 에러발생 해결과정 본문

개발노트/Python

pymysql.err.Error: Already closed 에러발생 해결과정

오지구영ojjy90 2021. 4. 9. 16:03
728x90
반응형

 

 

class MARIADB(DBCON):
    def __init__(self, **kwargs):
        self.dbms="MARIADB"
        self.port = kwargs["port"]
        super().__init__(**kwargs)

    def connectiondb(self):
        try:
            self.con = pymysql.connect(host=self.host, user=self.user, password=self.password, database=self.dbname, port=int(self.port), autocommit=True)
            return self.con
        except Exception as e:
            return self.get_error_msg(e)


    def version_check(self):
        self.version_query = "SELECT VERSION()"
        with self.con:
            with self.con.cursor() as cur:
                sql = self.version_query
                cur.execute(sql)
                version = cur.fetchone()
        return self.get_version_info(version)

    def exec_query(self):
        sql = """select * from tbl2"""
        with self.con as con:
            with con.cursor() as cur:
                print("sql test")
                cur.execute(sql)
                result = cur.fetchone()
                print("sql test")
                print(result)
                return result

if __name__ == "__main__":
    con_info=get_dict("secret.json")
    maria_db = MARIADB(host=con_info["MARIADB_HOST"],
                       user=con_info['MARIADB_USER'],
                       password=con_info['MARIADB_PASSWORD'],
                       dbname=con_info['MARIADB_DBNAME'],
                       port=con_info['MARIADB_PORT'])
    maria_db.version_check()
    maria_db.exec_query()

 

 

{
  "MARIADB_HOST": "127.0..0.1",
  "MARIADB_USER": "testuser",
  "MARIADB_PASSWORD": "testpassword",
  "MARIADB_DBNAME": "test",
  "MARIADB_PORT": "3306"
}

 

 

소스는 다음과 같고, secret.json에 데이터 베이스 연결정보가 정확하다는 가정하에 다음과 같은 에러가 발생한다.

 

    raise err.Error("Already closed")

pymysql.err.Error: Already closed

 

이상하다... 잘못한거 없는거 같은데..

 

db연결하고,

연결이 잘되었는지 버전확인하고,

쿼리문 날려서 결과 보고..

 

프로그램이 실행되면서 프로세스가 생성되고 

main함수에서 디비에 연결하고, 버전확인하고, select절 날려보고..

여기서 디비에 연결후 확인하는 과정에서 with절을 주목해야 한다.

버전확인하는 과정에서 

 

        with self.con:
            with self.con.cursor() as cur:
                sql = self.version_query
                cur.execute(sql)
                version = cur.fetchone()

 

 

이부분과 select날리는 과정에서

 

 

       with self.con as con:
            with con.cursor() as cur:
                print("sql test")
                cur.execute(sql)
                result = cur.fetchone()
                print("sql test")
                print(result)
                return result

 

이부분이다.

 

with절에서 이미 connection을 닫았는데 다시 connection을 열었다.

여기서 문제였다.

그렇다면 어떻게 해결할까?

with절이 시작되면 연결이 설정되고 with절이 끝나면 연결이 해제되기 때문에 with절 열때마다 db를 연결하면된다.

 

다음과 같이..

 

class MARIADB(DBCON):
    def __init__(self, **kwargs):
        self.dbms="MARIADB"
        self.port = kwargs["port"]
        super().__init__(**kwargs)

    def connectiondb(self):
        try:
            self.con = pymysql.connect(host=self.host, user=self.user, password=self.password, database=self.dbname, port=int(self.port), autocommit=True)
            return self.con
        except Exception as e:
            return self.get_error_msg(e)

    def version_check(self):
        self.version_query = "SELECT VERSION()"

        with self.connectiondb() as con:
            with con.cursor() as cur:
                sql = self.version_query
                cur.execute(sql)
                version = cur.fetchone()
        return self.get_version_info(version)

    def exec_query(self):
        sql = """select * from tbl2"""
        with self.connectiondb() as con:
            with con.cursor() as cur:
                cur.execute(sql)
                result = cur.fetchone()
                print(result)
                return result

 

 

 

전체소스는 제 깃으로

github.com/ojjy/dataeng/blob/master/libs/dbcon/dbcon.py

Comments