라이브러리 다운로드
pip install sqlalchemy
pip install pymysql
python과 mysql을 연동할 때 사용되는 드라이버
pip install cryptography
pyMySQL을 통해 MySQL에 접속할 때 인증이나 암호 관련된 처리를 해주는 라이브러리
데이터베이스 연결
# 라이브러리 import
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
# root 계정의 todos라는 비밀번호를 이용한다. 포트는 이렇게 사용하고 todos 데이터베이스를 사용한다. 라는 의미
DATABASE_URL = "mysql+pymysql://root:todos@127.0.0.1:3306/todos"
# 어느 SQL Alchemy를 이용해서 데이터베이스에 접속하기 위해서는 먼저 engine이라는 객체를 만들어야된다.
# echo = True : SQL Alchemy에 의해서 여러가지 쿼리가 대신 처리되는데 그 쿼리가 대신 처리될 때 어떤 sql이 사용됐는지 사용되는 시점에 사용되는 SQL을 출력해주는 옵션
engine = create_engine(DATABASE_URL, echo=True)
# Session이란 것을 생성해서 인스턴스를 통해 데이터베이스와 통신
# 자동 커밋, 플러쉬를 하지않고 수동으로 하겠다.
# bind = engine : 전달한 이 데이터베이스 UI를 통해서 어떤 엔진이라는 기체가 생성이 되고 그 엔진을 사용해서 실제로 Session을 만들 수 있게 된다.
SessionFactory = sessionmaker(autocommit = False, autoflush = False, bind = engine)
SQLAlchemy 전체 구조 이해하기
SQLAlchemy 전체 구조
내 Python 코드
↓
SQLAlchemy ← "번역가" 역할
↓
Engine ← "자동차 엔진" 역할 (DB 연결 담당)
↓
Connection Pool ← "연결 대기실" 역할
↓
Session ← "창구 직원" 역할 (실제 대화 담당)
↓
MySQL DB ← 실제 데이터 저장소
1. SQLAlchemy가 뭔지
SQLAlchemy 역할 비유
SQLAlchemy 없을 때
─────────────────────────────
Python 코드
↓
직접 SQL 작성
"SELECT * FROM todo WHERE id = 1"
↓
MySQL
SQLAlchemy 있을 때
─────────────────────────────
Python 코드
↓
Python으로 작성
session.get(ToDo, 1)
↓
SQLAlchemy가 SQL로 자동 번역
"SELECT * FROM todo WHERE id = 1"
↓
MySQL
💡 SQLAlchemy = Python 코드를 SQL로 자동 번역해주는 번역가
2. Engine이 뭔지
Engine 비유
DATABASE_URL = "mysql+pymysql://root:todos@127.0.0.1:3306/todos"
↑ ↑ ↑ ↑ ↑
어떤 DB 계정 비번 주소 DB이름
(MySQL)
Engine = 이 정보를 갖고 DB와 연결하는 방법을 알고 있는 객체
자동차로 비유하면:
Engine 비유
| 비유 | 실제 |
| 자동차 엔진 | Engine 객체 |
| 연료 | DATABASE_URL (어디에 어떻게 연결할지) |
| 시동 걸기 | create_engine() |
| 실제 주행 | Session이 담당 |
Engine 역할
# Engine은 실제로 연결을 맺지는 않아요
# "나는 이 DB에 이렇게 연결하는 방법을 알고 있어" 만 기억해두는 것
engine = create_engine(DATABASE_URL, echo=True)
# ↑
# SQL 실행될 때마다 콘솔에 출력해줌
# (개발할 때 디버깅용으로 씀)
# echo=True 덕분에 이런 로그가 콘솔에 찍히는 거예요
# INFO sqlalchemy.engine.Engine SELECT todo.id, todo.contents...
3. Connection Pool이 뭔지
Connection Pool 비유
Connection Pool = 연결 대기실
DB 연결을 미리 여러 개 만들어서 대기시켜 놓음
──────────────────────────────────────────
[연결1 대기중] [연결2 대기중] [연결3 대기중]
요청 들어오면
──────────────────────────────────────────
[연결1 사용중] [연결2 대기중] [연결3 대기중]
↑
GET /todos 요청이 이 연결 가져다 씀
요청 끝나면
──────────────────────────────────────────
[연결1 반납!] [연결2 대기중] [연결3 대기중]
💡 매번 연결을 새로 만들면 느리니까, 미리 만들어 놓고 돌려쓰는 것
4. Session이 뭔지
Session 비유
은행으로 비유하면:
Engine = 은행 건물 (DB와 연결하는 방법 알고 있음)
Connection = 은행 창구 (실제 연결)
Session = 창구 직원 (실제로 대화하는 사람)
나(Python 코드)
↓
Session(창구 직원)한테 요청
"todo 목록 조회해줘"
↓
Session이 SQL로 번역해서 DB에 전달
"SELECT * FROM todo"
↓
결과 받아서 나한테 전달
Session이 하는 일들
session = SessionFactory()
# 1. 조회
todos = session.scalars(select(ToDo))
# 2. 추가
new_todo = ToDo(contents="새 할일", is_done=False)
session.add(new_todo)
session.commit() # ← 실제 DB에 반영 (수동 커밋)
# 3. 수정
todo = session.get(ToDo, 1)
todo.is_done = True
session.commit() # ← 수동 커밋
# 4. 삭제
session.delete(todo)
session.commit() # ← 수동 커밋
# 5. 닫기
session.close() # ← Connection Pool에 연결 반납
5. SessionFactory 설정 완전 분해
SessionFactory 설정 의미
SessionFactory = sessionmaker(
autocommit=False, # 자동으로 commit 하지 마
# → 내가 직접 session.commit() 해야 DB에 반영됨
# → 실수로 잘못된 데이터 저장 방지
autoflush=False, # 자동으로 flush 하지 마
# → flush = "변경사항을 DB에 예고편으로 보내기"
# → 내가 원할 때만 DB에 보내겠다
bind=engine # 이 engine을 사용해서 연결해
# → 어떤 DB에 연결할지 알려주는 것
)
autocommit 과 autoflush 차이
| 설정 | False일 때 | True일 때 |
| autocommit | session.commit() 직접 호출해야 DB 반영 | 자동으로 즉시 반영 |
| autoflush | 내가 원할 때만 DB에 예고편 전송 | 쿼리 전에 자동으로 예고편 전송 |
6. 전체 흐름 한눈에 보기
실제 API 요청 전체 흐름
GET /todos 요청
↓
Depends(get_db) 실행
↓
SessionFactory() ← Connection Pool에서 연결 하나 가져옴
↓
session 생성 ← 이 session으로 DB와 대화 시작
↓
session.scalars(select(ToDo))
↓
Engine이 SQL로 번역
"SELECT todo.id, todo.contents, todo.is_done FROM todo"
↓
MySQL DB에서 결과 반환
↓
Python 객체(ToDo)로 변환
↓
JSON 응답 반환
↓
session.close() ← Connection Pool에 연결 반납
💡 핵심 요약:
SQLAlchemy = Python ↔ SQL 번역가
Engine = DB 연결 방법을 알고 있는 엔진
Connection Pool = 연결을 미리 만들어 놓는 대기실
Session = 실제로 DB와 대화하는 창구 직원
autocommit=False = 내가 직접 commit 해야 DB에 반영됨
파이썬 콘솔에 입력
from database.connection import SessionFactory
- 먼저 SessionFactory를 import
session = SessionFactory()
- session 객체 먼저 생성
from sqlalchemy import select
- select 쿼리를 사용하기 위해 sqlalchemy import
session.scalar(select(1))

- select(1)을 출력하는 즉 1을 출력하는 쿼리를 데이터베이스에 날려보기
- 실제로 어떤 데이터가 의미 있는 데이터가 출력이 되진 않지만 이 세션을 통해서 이렇게 쿼리를 날리는 것만으로도 데이터베이스에 연결됐는지 확인할 수 있다.
- 이런 로그들이 나타나는 경우는 앞서 echo옵션을 줬기 때문이다.
- 그래서 로그를 확인을 해보면 데이터베이스에 연결을 해서 이런식으로 SELECT 쿼리가 발생했다는 것을 알 수 있다.
- 정상적으로 처리가 됐기 때문에 1이 출력된다.
- 만약 도커가 정상적으로 돌고 있지 않거나 todos 데이터베이스가 잘 생성되지 않았다면 쿼리를 날려도 아무것도 출력이 되지 않는다.
'FastAPI > 데이터베이스' 카테고리의 다른 글
| ORM 적용 - GET 전체 조회 API / Python - Generator (0) | 2026.06.14 |
|---|---|
| ORM 모델링 (1) | 2026.06.09 |
| DDL - Create Table (0) | 2026.06.04 |
| MySQL 컨테이너 실행 (0) | 2026.05.19 |
| sqlalchemy (0) | 2026.05.19 |