08 SQL INSERT, UPDATE, DELETE 명령어 실습
1. 인트로
데이터를 넣고(INSERT(인서트)), 수정하고(UPDATE(업데이트)), 삭제하는(DELETE(딜리트)) 명령어를 익힌다. 이 세 명령어는 DML(Data Manipulation Language(데이터 매니퓰레이션 랭귀지))에 속하며, 리액트 앱의 회원가입, 정보 수정, 탈퇴 기능의 핵심이다.
2. 실습 DB 준비
1import sqlite32
3conn = sqlite3.connect("sns.db")4cur = conn.cursor()5
6cur.execute("""7 CREATE TABLE IF NOT EXISTS posts (8 id INTEGER PRIMARY KEY AUTOINCREMENT,9 username TEXT NOT NULL,10 content TEXT NOT NULL,11 likes INTEGER DEFAULT 0,12 created_at TEXT DEFAULT (datetime('now','localtime'))13 )14""")15conn.commit()16print("posts 테이블 생성 완료")3. SQL INSERT 명령어의 이해 및 실습
3.1. 기본 INSERT
1# 게시글 한 개 삽입2cur.execute(3 "INSERT INTO posts (username, content) VALUES (?, ?)",4 ("김철수", "오늘 점심 맛있었다 🍜")5)6conn.commit()7print("게시글 작성 완료, id:", cur.lastrowid)코드 설명:
- 3행: 값을 넣을 컬럼명을 명시한다. id, likes, created_at은 DEFAULT 값이 있어 생략 가능하다.
- 4행:
?플레이스홀더에 실제 값을 전달한다. - 6행:
cur.lastrowid— 방금 삽입된 행의 id를 반환한다.
3.2. 여러 행 한 번에 삽입 — executemany
1sample_posts = [2 ("이영희", "오늘 운동 완료! 💪"),3 ("박지민", "새 앨범 나왔다!! 🎵"),4 ("최수진", "비 오는 날 커피 ☕"),5 ("홍길동", "파이썬 공부 중 🐍"),6 ("강민준", "주말 영화 추천 받아요 🎬"),7]8
9cur.executemany(10 "INSERT INTO posts (username, content) VALUES (?, ?)",11 sample_posts12)13conn.commit()14print(f"{cur.rowcount}개 게시글 삽입 완료")코드 설명:
- 1~7행: 삽입할 데이터를 튜플 리스트로 준비한다.
- 9행:
executemany()는 같은 SQL을 리스트 길이만큼 반복 실행한다. - 13행:
cur.rowcount는 영향받은 행의 수를 반환한다.
3.3. 삽입 결과 확인
1import pandas as pd2df = pd.read_sql("SELECT * FROM posts", conn)3print(df)4. SQL UPDATE 명령어의 이해 및 실습
4.1. 단일 행 수정
1# id가 1인 게시글의 likes를 10으로 수정2cur.execute("UPDATE posts SET likes = 10 WHERE id = 1")3conn.commit()4print("좋아요 업데이트 완료")코드 설명:
- 2행:
SET likes = 10— likes 컬럼 값을 10으로 변경한다. - 2행:
WHERE id = 1— id가 1인 행만 수정한다. WHERE가 없으면 전체 행이 수정된다.
4.2. 조건에 맞는 여러 행 수정
1# 좋아요 0인 게시글을 1로 초기화2cur.execute("UPDATE posts SET likes = 1 WHERE likes = 0")3conn.commit()4print(f"{cur.rowcount}개 게시글 좋아요 초기화")4.3. 현재 값 기준으로 수정
1# id=2 게시글 좋아요 +5 증가2cur.execute("UPDATE posts SET likes = likes + 5 WHERE id = 2")3conn.commit()4
5# 확인6cur.execute("SELECT id, username, likes FROM posts WHERE id = 2")7print("수정 후:", cur.fetchone())코드 설명:
- 2행:
likes = likes + 5— 기존 값에 5를 더한다. 리액트 앱의 좋아요 버튼 클릭 시 사용되는 패턴이다.
5. SQL DELETE 명령어의 이해 및 실습
5.1. 특정 행 삭제
1# id가 3인 게시글 삭제2cur.execute("DELETE FROM posts WHERE id = 3")3conn.commit()4print(f"{cur.rowcount}개 게시글 삭제 완료")코드 설명:
- 2행:
WHERE id = 3— id가 3인 행만 삭제한다. 조건이 없으면 전체 삭제된다.
5.2. 조건으로 여러 행 삭제
1# 좋아요 2 이하인 게시글 삭제2cur.execute("DELETE FROM posts WHERE likes <= 2")3conn.commit()4print(f"{cur.rowcount}개 비인기 게시글 삭제")5.3. 삭제 전 확인 패턴 (권장)
1# 삭제 전에 먼저 SELECT로 확인2cur.execute("SELECT id, username, content FROM posts WHERE likes <= 2")3targets = cur.fetchall()4print("삭제 예정 게시글:")5for t in targets:6 print(f" id={t[0]} {t[1]}: {t[2]}")7
8# 확인 후 삭제9ans = input("삭제하시겠습니까? (y/n): ")10if ans.lower() == 'y':11 cur.execute("DELETE FROM posts WHERE likes <= 2")12 conn.commit()13 print("삭제 완료")14else:15 print("취소")코드 설명:
- 2~6행: 삭제 전에 SELECT로 대상을 먼저 확인한다. 실무에서 권장하는 패턴이다.
- 9~13행: 사용자 입력을 받아 최종 확인 후 삭제한다.
6. 트랜잭션(Transaction(트랜잭션)) 이해
트랜잭션은 여러 작업을 하나의 단위로 묶는 개념이다. 모두 성공하거나, 하나라도 실패하면 전체를 되돌린다.
1try:2 # 게시글 작성 + 작성자 포인트 증가를 하나의 트랜잭션으로 처리3 cur.execute("INSERT INTO posts (username, content) VALUES (?, ?)",4 ("테스트유저", "트랜잭션 테스트 게시글"))5
6 # 의도적 오류 발생 (테스트용)7 # cur.execute("UPDATE 없는테이블 SET x=1")8
9 conn.commit() # 모두 성공하면 저장10 print("게시글 작성 성공")11
12except Exception as e:13 conn.rollback() # 실패하면 전체 되돌리기14 print(f"오류 발생, 되돌림: {e}")코드 설명:
- 1행:
try블록 안에서 여러 SQL을 실행한다. - 9행: 모두 정상이면
commit()으로 저장한다. - 12행: 하나라도 실패하면
rollback(롤백)으로 이전 상태로 되돌린다.
7. 활용 Plus — 리액트 연동 관점
리액트 SNS 앱의 각 기능과 SQL의 매핑이다.
| 리액트 기능 | SQL 명령 |
|---|---|
| 게시글 작성 | INSERT INTO posts |
| 좋아요 클릭 | UPDATE posts SET likes = likes + 1 WHERE id = ? |
| 게시글 수정 | UPDATE posts SET content = ? WHERE id = ? |
| 게시글 삭제 | DELETE FROM posts WHERE id = ? |
8. 문제풀기
동일한 SQL 문을 여러 데이터에 반복 실행할 때 코드를 간결하게 만들고 성능을 향상시키기 위해서이다.
테이블의 모든 행이 수정된다. 반드시 WHERE로 수정 대상을 지정해야 한다.
트랜잭션 도중 오류가 발생했을 때 변경사항 전체를 취소하고 이전 상태로 되돌릴 때 사용한다.
lastrowid: 마지막으로 INSERT된 행의 id 값을 반환한다. rowcount: 마지막 SQL로 영향받은 행의 수를 반환한다.