[Python3 - PyMySQL] 1. with 구문을 이용한 PyMySQL 접속 테스트

2021. 2. 2. 17:39Python/Basic

반응형
  1. PyMySQL?
  2. 테스트용 DB 레코드 추가
  3. DB 연결 테스트
    3.1. try ... finally 구문
    3.2. with 구문 이용
  4. 결과

1. PyMySQL?

MySQL 서버와 MariaDB 서버 연결을 지원하는 MySQL client 라이브러리입니다.
대부분의 public API는 mysqlclient와 MySQLdb에 호환됩니다.

CPython 3.6 이상 버전과 PyPy 3.x 버전에서 지원되며, 데이터베이스 서버는 MySQL 5.6 이상 버전과 MariaDB 10.x 버전을 지원합니다.

python 스크립트 파일에서 pymysql을 사용하기 위해서는 먼저, PyMySQL 패키지를 설치해야합니다.
사용하고 있는 가상환경 또는 전역환경에 PyMySQL을 설치합니다.

pip install PyMySQL

2. 테스트용 DB 레코드 추가

테스트에 활용될 테이블을 생성한 후 레코드를 추가합니다.

CREATE TABLE `users` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  `age` int(11) unsigned DEFAULT NULL,
  `email` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT 'Y',
  `created_dt` datetime DEFAULT NULL,
  `type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `UX_USERS_EMAIL` (`email`),
  CONSTRAINT `CONSTRAINT_1` CHECK (`age` > 0)
);
INSERT INTO `users` (`id`, `name`, `age`, `email`, `status`, `created_dt`, `type`) VALUES
('1','jini','29','jini@jiniworld.me','Y','2020-12-22 15:42:20','1'),
('2','sol','33','sol@jiniworld.me','Y','2020-12-22 15:42:23','2'),
('3','coco','34','coco@c.com','Y','2020-12-22 17:13:21','2'),
('4','lily','22','lily@ll.com','Y','2020-12-29 10:51:17','1');

3. DB 연결 테스트

pymysql 객체의 connect 메서드를 이용하여 DB를 연결할 수 있습니다.

conn = pymysql.connect(host='127.0.0.1', port=3306, user='test', password='test',
                       db='test_db', charset="utf8", cursorclass=pymysql.cursors.DictCursor)
  • host
    • Database Server가 위치한 호스트주소
  • port
    • Database Server 포트
  • user
    • Database Server 로그인 username
  • password
    • Database Server 로그인 password
  • db (= database)
    • 연결할 database
  • charset
    • 캐릭터 셋
  • cursorclass
    • 커서 클래스
    • pymysql.cursors.DictCursor
      • 읽어들인 레코드(row)를 dictionary 형태로 반환

위에서 생성한 conn 객체의 cursor 메서드를 이용하여 쿼리를 실행시킬 수 있습니다.

cur = conn.cursor()

conn, cur 객체를 이용하여 간단한 조회를 실행해봅시다.

3.1. try ... finally 구문

if __name__ == '__main__':
    try:
        conn = pymysql.connect(host='127.0.0.1', port=3306, user='test', password='test', db='test_db', charset="utf8",
                               cursorclass=pymysql.cursors.DictCursor)
        try:
            cur = conn.cursor()
            sql = '''
            SELECT * from users
            '''
            cur.execute(sql)
            print(sql)
            results = cur.fetchall()
            for result in results:
                print(result)
        finally:
            cur.close()
    finally:
        conn.close()
    print('\nfinish!\n', '-----' * 20)
  • execute(query)
    • query를 실행합니다.
  • fetchall()
    • 조회된 결과값을 모두 fetch 합니다.

cur, conn 객체는 사용후 close하는 작업이 필요합니다.
객체 이용중 에러가 발생되었을 때, close하는 작업을 반드시 처리하기 위해 try ... finally 구문 설정을 추가하였습니다.
※ finally 블럭을 설정할 경우, try 블럭에서 에러가 발생되었을시 finally를 반드시 실행합니다.

3.2. with 구문 이용

with 구문은 __enter__, __exit__ magic method가 정의된 객체에서 사용할 수 있는 구문으로,
with 블럭 시작점에서 __enter__ 메서드를 실행하고, with 블럭을 끝내기 전에 __exit__ 메서드를 실행합니다. [Python 3 Docs 참고]

connect 메서드와 cursor 메서드에는 __enter__, __exit__ magic method가 정의 되어있고, __exit__ 메서드에는 self.close() 가 정의되어있기 때문에 with 구문을 이용하면 깔끔하게 코드를 정의할 수 있습니다.

with 구문을 적용한 코드입니다.

import pymysql


if __name__ == '__main__':
    with pymysql.connect(host='127.0.0.1', user='test', password='test', port=3306, db='test_db',
                         charset="utf8", cursorclass=pymysql.cursors.DictCursor) as conn:
        with conn.cursor() as cur:
            sql = '''
            SELECT * from users
            '''
            cur.execute(sql)
            print(sql)
            results = cur.fetchall()
            for result in results:
                print(result)
    print('\nfinish!\n', '-----' * 20)

try .. finally 문법에 비해 매우 직관적이며, close를 빼먹는 일을 방지할 수 있습니다.

4. 결과

python파일을 실행하면 아래와 같은 콘솔로그를 출력됩니다.

            SELECT * from users

{'id': 1, 'name': 'jini', 'age': 29, 'email': 'jini@jiniworld.me', 'status': 'Y', 'created_dt': datetime.datetime(2020, 12, 22, 15, 42, 20), 'type': '1'}
{'id': 2, 'name': 'sol', 'age': 33, 'email': 'sol@jiniworld.me', 'status': 'Y', 'created_dt': datetime.datetime(2020, 12, 22, 15, 42, 23), 'type': '2'}
{'id': 3, 'name': 'coco', 'age': 34, 'email': 'coco@c.com', 'status': 'Y', 'created_dt': datetime.datetime(2020, 12, 22, 17, 13, 21), 'type': '2'}
{'id': 4, 'name': 'lily', 'age': 22, 'email': 'lily@ll.com', 'status': 'Y', 'created_dt': datetime.datetime(2020, 12, 29, 10, 51, 17), 'type': '1'}

finish!
 ----------------------------------------------------------------------------------------------------

커서가 pymysql.cursors.DictCursor 로 설정되어있기 때문에 아래와 같이 dictionary형태로 레코드가 표현됩니다.


++

  • with 구문을 이용한 MySQL 접속 테스트
728x90
반응형