파이썬 MySQL? PyMySQL이면 끝! 설치부터 CRUD까지 완벽 가이드
파이썬은 다양한 데이터베이스와의 연동을 지원하는 강력한 라이브러리 생태계를 가지고 있습니다. 그중에서도 MySQL 데이터베이스를 파이썬 환경에서 손쉽게 제어하고자 할 때 PyMySQL은 훌륭한 선택지입니다. PyMySQL은 순수 파이썬으로 작성된 MySQL 클라이언트 라이브러리로, DB-API (PEP 249) 명세를 따르기 때문에 사용법이 직관적이고 다른 데이터베이스 라이브러리와 유사한 경험을 제공합니다.
이번 포스팅에서는 PyMySQL을 활용하여 파이썬에서 MySQL 데이터베이스에 접속하고, 기본적인 CRUD(Create, Read, Update, Delete) 작업을 수행하는 방법에 대해 단계별로 알아보겠습니다.
1. PyMySQL 설치 및 준비
가장 먼저 PyMySQL 라이브러리를 설치해야 합니다. pip를 사용하여 간단하게 설치할 수 있습니다.
# 터미널 또는 명령 프롬프트에서 실행
pip install pymysql
설치가 완료되었다면, 파이썬 스크립트에서 PyMySQL을 임포트하여 사용할 준비를 합니다.
import pymysql
2. MySQL 데이터베이스 연결 설정
데이터베이스 작업을 시작하기 위해서는 먼저 MySQL 서버에 연결해야 합니다. pymysql.connect()
함수를 사용하여 연결 객체를 생성합니다. 이때 필요한 주요 매개변수는 다음과 같습니다.
host
: 데이터베이스 서버의 호스트 주소 (예: 'localhost' 또는 IP 주소)port
: MySQL 서버 포트 번호 (기본값: 3306)user
: MySQL 사용자 이름password
(또는passwd
): MySQL 사용자 비밀번호db
(또는database
): 연결할 데이터베이스 이름charset
: 문자 인코딩 방식 (예: 'utf8mb4' 권장)
# 데이터베이스 연결 정보 (실제 환경에 맞게 수정하세요)
db_config = {
'host': 'localhost',
'port': 3306,
'user': 'your_user',
'password': 'your_password',
'db': 'your_database',
'charset': 'utf8mb4'
}
try:
# 데이터베이스에 연결
conn = pymysql.connect(**db_config)
print("MySQL 데이터베이스에 성공적으로 연결되었습니다.")
except pymysql.MySQLError as e:
print(f"데이터베이스 연결 중 오류 발생: {e}")
exit() # 연결 실패 시 프로그램 종료
3. SQL 실행을 위한 커서(Cursor) 생성
데이터베이스에 성공적으로 연결했다면, SQL 쿼리를 실행하고 결과를 다루기 위해 커서(cursor) 객체를 생성해야 합니다. 커서는 데이터베이스 내에서 현재 위치를 가리키며, 쿼리 실행 및 결과 세트 관리를 담당합니다.
# conn 객체는 이전 단계에서 생성된 연결 객체입니다.
cursor = conn.cursor()
4. 데이터베이스 작업의 시작: 테이블 생성 (CREATE TABLE)
이제 커서를 사용하여 SQL 문을 실행할 수 있습니다. 먼저 간단한 예시로 members
라는 이름의 테이블을 생성해보겠습니다.
try:
# 테이블 생성 SQL 쿼리
create_table_query = """
CREATE TABLE IF NOT EXISTS members (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
"""
cursor.execute(create_table_query)
conn.commit() # 변경사항을 데이터베이스에 영구적으로 반영
print("members 테이블이 성공적으로 생성되었거나 이미 존재합니다.")
except pymysql.MySQLError as e:
print(f"테이블 생성 중 오류 발생: {e}")
conn.rollback() # 오류 발생 시 변경사항 철회
CREATE TABLE IF NOT EXISTS
구문은 테이블이 존재하지 않을 경우에만 새로 생성합니다. conn.commit()
은 INSERT
, UPDATE
, DELETE
, CREATE
등 데이터베이스의 상태를 변경하는 DML(Data Manipulation Language)이나 DDL(Data Definition Language) 실행 후 필수적으로 호출하여 변경 사항을 확정합니다.
5. 데이터 추가하기: INSERT
생성된 members
테이블에 새로운 데이터를 추가해보겠습니다. SQL 인젝션 공격을 방지하고 코드를 더 깔끔하게 만들기 위해 플레이스홀더(%s
)를 사용하는 것이 좋습니다.
try:
# 단일 데이터 삽입
insert_query_single = "INSERT INTO members (name, email) VALUES (%s, %s)"
member_data_single = ('Alice Wonderland', 'alice@example.com')
cursor.execute(insert_query_single, member_data_single)
# 여러 데이터 한 번에 삽입 (executemany 사용)
members_data_multiple = [
('Bob The Builder', 'bob@example.com'),
('Charlie Chaplin', 'charlie@example.com')
]
insert_query_multiple = "INSERT INTO members (name, email) VALUES (%s, %s)"
cursor.executemany(insert_query_multiple, members_data_multiple)
conn.commit()
print(f"{cursor.rowcount}개의 데이터가 성공적으로 삽입되었습니다.") # executemany의 경우 마지막 실행된 쿼리의 rowcount
except pymysql.MySQLError as e:
print(f"데이터 삽입 중 오류 발생: {e}")
conn.rollback()
6. 데이터 조회하기: SELECT
테이블에서 데이터를 가져오는 방법은 여러 가지가 있습니다. fetchone()
, fetchall()
, fetchmany()
메소드를 활용할 수 있습니다.
try:
select_query = "SELECT id, name, email, created_at FROM members"
cursor.execute(select_query)
print("\n--- fetchone() ---")
# 첫 번째 행만 가져오기
row = cursor.fetchone()
if row:
print(row) # (1, 'Alice Wonderland', 'alice@example.com', datetime.datetime(...))
# cursor.execute(select_query) # 다시 실행해야 fetchall 등이 제대로 동작
print("\n--- fetchall() ---")
# 모든 행 가져오기
cursor.execute(select_query) # SELECT 쿼리를 다시 실행하여 커서 위치 초기화
rows = cursor.fetchall()
for r in rows:
print(r)
print("\n--- fetchmany(size) ---")
# 지정된 수(size)만큼의 행 가져오기
cursor.execute(select_query) # SELECT 쿼리를 다시 실행
some_rows = cursor.fetchmany(2) # 처음 2개 행 가져오기
for r in some_rows:
print(r)
except pymysql.MySQLError as e:
print(f"데이터 조회 중 오류 발생: {e}")
조회 결과는 기본적으로 튜플의 리스트 형태로 반환됩니다. 딕셔너리 형태로 받고 싶다면 pymysql.cursors.DictCursor
를 커서 생성 시 지정할 수 있습니다: cursor = conn.cursor(pymysql.cursors.DictCursor)
.
7. 데이터 수정하기: UPDATE
특정 조건에 맞는 레코드의 정보를 변경할 수 있습니다.
try:
update_query = "UPDATE members SET email = %s WHERE name = %s"
new_email = 'alice.new@example.com'
name_to_update = 'Alice Wonderland'
cursor.execute(update_query, (new_email, name_to_update))
conn.commit()
if cursor.rowcount > 0:
print(f"'{name_to_update}'의 이메일이 성공적으로 업데이트되었습니다.")
else:
print(f"'{name_to_update}' 이름을 가진 멤버를 찾을 수 없습니다.")
except pymysql.MySQLError as e:
print(f"데이터 업데이트 중 오류 발생: {e}")
conn.rollback()
8. 데이터 삭제하기: DELETE
테이블에서 특정 조건에 맞는 레코드를 삭제합니다.
try:
delete_query = "DELETE FROM members WHERE name = %s"
name_to_delete = 'Charlie Chaplin'
cursor.execute(delete_query, (name_to_delete,)) # 인자가 하나라도 튜플 형태로 전달
conn.commit()
if cursor.rowcount > 0:
print(f"'{name_to_delete}' 멤버가 성공적으로 삭제되었습니다.")
else:
print(f"'{name_to_delete}' 이름을 가진 멤버를 찾을 수 없습니다.")
except pymysql.MySQLError as e:
print(f"데이터 삭제 중 오류 발생: {e}")
conn.rollback()
9. 리소스 정리: 연결 종료
데이터베이스 작업이 모두 완료되면, 사용했던 리소스를 해제하기 위해 커서와 연결 객체를 닫아주어야 합니다. 이는 시스템 리소스를 효율적으로 관리하고 잠재적인 문제를 방지하는 데 중요합니다.
# 모든 작업이 끝난 후
if 'cursor' in locals() and cursor:
cursor.close()
if 'conn' in locals() and conn:
conn.close()
print("MySQL 데이터베이스 연결이 종료되었습니다.")
10. with
문을 활용한 자동 리소스 관리
파이썬의 with
문을 사용하면 코드 블록이 종료될 때 자동으로 리소스를 해제해주므로, close()
메소드를 명시적으로 호출하는 것을 잊어버릴 위험을 줄일 수 있습니다.
# with 문을 사용한 예시
try:
with pymysql.connect(**db_config) as conn:
with conn.cursor() as cursor:
# 테이블 생성
cursor.execute("""
CREATE TABLE IF NOT EXISTS items (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50),
price DECIMAL(10, 2)
)
""")
conn.commit() # DDL은 commit 필요
# 데이터 삽입
cursor.execute("INSERT INTO items (name, price) VALUES (%s, %s)", ('Laptop', 1200.50))
conn.commit() # DML도 commit 필요
# 데이터 조회
cursor.execute("SELECT * FROM items")
item = cursor.fetchone()
if item:
print(f"조회된 아이템: {item}")
print("모든 작업이 완료되고 연결이 자동으로 종료되었습니다.")
except pymysql.MySQLError as e:
print(f"with 문 사용 중 오류 발생: {e}")
# conn.rollback()은 with 문 안에서 예외 발생 시 자동으로 처리되지 않으므로,
# 트랜잭션 관리가 중요하다면 명시적인 예외 처리와 롤백이 필요할 수 있습니다.
# 혹은, 연결 자체에 autocommit=True 옵션을 줄 수도 있지만, 권장되지는 않습니다.
마무리
지금까지 PyMySQL 라이브러리를 사용하여 파이썬에서 MySQL 데이터베이스와 상호작용하는 기본적인 방법들을 살펴보았습니다. PyMySQL은 설치부터 연결, CRUD 작업 수행, 리소스 관리에 이르기까지 직관적이고 효율적인 인터페이스를 제공합니다.
참고: PyMySQL은 MySQL 전용 라이브러리입니다. PostgreSQL에는 psycopg2
, SQLite에는 파이썬 내장 sqlite3
모듈, MS SQL Server에는 pyodbc
또는 pymssql
등 각 RDBMS에 맞는 라이브러리를 사용해야 합니다.
이 가이드가 PyMySQL을 시작하는 데 도움이 되셨기를 바랍니다. 더 복잡한 쿼리, 트랜잭션 관리, 저장 프로시저 호출 등 PyMySQL의 다양한 기능을 탐색해보세요!