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