04 Pandas를 활용한 SQL 명령문 실행
1. 인트로
pandas(판다스)는 데이터를 표(DataFrame(데이터프레임)) 형태로 다루는 파이썬 라이브러리이다. sqlite3와 pandas를 함께 사용하면 SQL 조회 결과를 엑셀처럼 보기 좋게 확인하고, 분석하고, 저장할 수 있다.
2. DB 데이터 일괄 추가 실습
2.1. 실습용 DB 준비
1import sqlite32import pandas as pd3
4conn = sqlite3.connect("store.db")5cur = conn.cursor()6
7cur.execute("""8 CREATE TABLE IF NOT EXISTS products (9 id INTEGER PRIMARY KEY AUTOINCREMENT,10 name TEXT NOT NULL,11 category TEXT,12 price INTEGER,13 stock INTEGER DEFAULT 014 )15""")16conn.commit()코드 설명:
- 2행: pandas(판다스) 라이브러리를
pd라는 별명으로 불러온다. - 4행:
store.db파일을 생성하거나 연결한다. - 7~14행: 상품 테이블을 생성한다. 이미 존재하면 건너뛴다.
2.2. CSV(씨에스브이) 파일로 대량 데이터 삽입
엑셀 또는 CSV 파일의 데이터를 DB에 한 번에 넣는 방법이다. 먼저 pandas로 샘플 데이터를 만들어 삽입한다.
1# 샘플 데이터 생성2data = {3 "name" : ["아이패드", "갤럭시탭", "맥북프로", "갤럭시북", "아이폰15", "갤럭시S24"],4 "category": ["태블릿", "태블릿", "노트북", "노트북", "스마트폰", "스마트폰"],5 "price" : [1200000, 800000, 2800000, 1500000, 1350000, 1250000],6 "stock" : [30, 45, 15, 20, 60, 55],7}8
9df = pd.DataFrame(data)10
11# DataFrame(데이터프레임)을 DB에 한 번에 삽입12df.to_sql("products", conn, if_exists="append", index=False)13conn.commit()14
15print(f"총 {len(df)}개 상품 삽입 완료")16print(df)코드 설명:
- 2~7행: 딕셔너리(Dictionary(딕셔너리)) 형태로 샘플 데이터를 만든다.
- 9행:
pd.DataFrame()으로 표 형태의 데이터프레임을 생성한다. - 12행:
to_sql()은 데이터프레임을 DB 테이블에 바로 저장한다."products": 저장할 테이블 이름if_exists="append": 테이블이 이미 있으면 데이터를 추가한다."replace"는 덮어쓴다.index=False: 데이터프레임의 인덱스(0, 1, 2…)는 저장하지 않는다.
3. Pandas를 활용한 DB 테이블의 확인
3.1. read_sql() — SQL 결과를 데이터프레임으로
1# 전체 상품 조회2df_all = pd.read_sql("SELECT * FROM products", conn)3print(df_all)실행 결과:
1 id name category price stock20 1 아이패드 태블릿 1200000 3031 2 갤럭시탭 태블릿 800000 4542 3 맥북프로 노트북 2800000 1553 4 갤럭시북 노트북 1500000 2064 5 아이폰15 스마트폰 1350000 6075 6 갤럭시S24 스마트폰 1250000 55코드 설명:
- 2행:
pd.read_sql(SQL문, 연결객체)는 SQL 실행 결과를 바로 데이터프레임으로 변환한다. - 3행: 주피터 노트북에서는
print()없이 변수명만 입력해도 표 형태로 보인다.
3.2. 조건 필터링
1# 100만원 이상 상품만 조회2df_high = pd.read_sql(3 "SELECT name, price FROM products WHERE price >= 1000000",4 conn5)6print(df_high)3.3. 데이터프레임으로 분석
1# 카테고리별 평균 가격 계산2df_all = pd.read_sql("SELECT * FROM products", conn)3
4avg_price = df_all.groupby("category")["price"].mean()5print("=== 카테고리별 평균 가격 ===")6print(avg_price)실행 결과:
1=== 카테고리별 평균 가격 ===2category3노트북 2150000.04스마트폰 1300000.05태블릿 1000000.0코드 설명:
- 4행:
groupby("category")는 category 값이 같은 행끼리 묶는다. - 4행:
["price"].mean()은 묶인 그룹에서 price 컬럼의 평균을 계산한다.
3.4. 데이터프레임 → CSV 저장
1df_all = pd.read_sql("SELECT * FROM products", conn)2df_all.to_csv("products_backup.csv", index=False, encoding="utf-8-sig")3print("CSV 저장 완료!")코드 설명:
- 2행:
to_csv()로 데이터프레임을 CSV 파일로 저장한다. encoding="utf-8-sig": 엑셀에서 한글이 깨지지 않도록 BOM(봄) 인코딩을 사용한다.
4. 활용 Plus
4.1. 외부 CSV → DB 저장
실제 데이터 파일을 DB에 저장하는 실무 패턴이다.
1# 외부 CSV를 읽어 DB에 저장2df_csv = pd.read_csv("외부데이터.csv")3df_csv.to_sql("external_table", conn, if_exists="replace", index=False)4conn.commit()5print("외부 데이터 저장 완료")코드 설명:
- 2행:
pd.read_csv()로 CSV 파일을 데이터프레임으로 읽는다. - 3행:
if_exists="replace"는 테이블이 있으면 삭제 후 새로 만들어 저장한다.
4.2. 리액트 연동과의 관계
리액트에서 상품 목록 페이지를 만들 때 파이썬 API 서버는 아래와 같이 동작한다.
1리액트 → GET /api/products2 → SELECT * FROM products (pandas 또는 sqlite3)3 → JSON 변환 (df.to_dict('records'))4 → 리액트로 반환df.to_dict('records')는 데이터프레임을 JSON(제이슨) 형태로 변환하는 핵심 메서드이다.
1df = pd.read_sql("SELECT * FROM products", conn)2json_data = df.to_dict("records")3print(json_data[:2])실행 결과:
1[{'id': 1, 'name': '아이패드', 'category': '태블릿', 'price': 1200000, 'stock': 30},2 {'id': 2, 'name': '갤럭시탭', 'category': '태블릿', 'price': 800000, 'stock': 45}]5. 문제풀기
cur.execute() + fetchall()은 결과를 튜플 리스트로 반환한다. pd.read_sql()은 결과를 데이터프레임(표 형태)으로 반환하여 분석 및 가공이 쉽다.
append: 기존 테이블에 데이터를 추가한다. replace: 기존 테이블을 삭제하고 새로 만들어 저장한다.
to_csv() 호출 시 encoding=‘utf-8-sig’ 옵션을 사용한다.
df.to_dict(‘records’) 리스트 안에 딕셔너리 형태로 변환되어 API 응답값으로 사용하기 적합하다.