[Flask-④] 파이썬 ORM과 데이터베이스 연동 (SQLAlchemy)
파이썬 ORM과 데이터베이스 연동 (SQLAlchemy)
데이터를 손쉽게 저장하고 꺼낼 수 있다면 얼마나 편할까요?
SQL 없이 파이썬 객체만으로 DB를 다룰 수 있는 방법,
지금 바로 알아보세요!
안녕하세요, 여러분!
Flask 웹 개발의 핵심 기능 중 하나는 바로 데이터베이스 연동이죠.
특히 게시판, 블로그, 사용자 시스템 등에서 데이터를 저장하고 불러오는 기능은 필수입니다.
오늘은 ORM(Object Relational Mapping) 개념부터 Flask-SQLAlchemy
를 활용한 실제 데이터베이스 연동까지, 실습 중심으로 하나씩 차근차근 배워볼 거예요.
SQLite를 사용해 복잡한 환경 설정 없이 시작하고, 직접 모델을 정의하고 테이블을 생성해보며 ORM의 편리함을 체감해보세요.
실습 예제를 따라하면서 여러분만의 데이터 저장 시스템을 만들어봅시다!
목차
1. ORM과 SQLAlchemy란? 🧠
여러분은 SQL 문을 일일이 작성하며 데이터를 관리하던 경험, 있으신가요?
테이블 생성, 삽입, 조회, 수정, 삭제… 이 모든 작업을 SQL 없이 파이썬 객체만으로 할 수 있다면 얼마나 편할까요?
바로 그걸 가능하게 해주는 기술이 ORM (Object Relational Mapping)입니다.
ORM이란 무엇인가요?
ORM은 객체 지향 프로그래밍(OOP)과 관계형 데이터베이스(RDB)를 연결해주는 브릿지 역할을 합니다.
즉, 테이블 → 클래스, 레코드 → 객체로 매핑해주는 거죠.
파이썬 클래스와 객체를 통해 데이터를 조작하고 관리할 수 있어, 마치 메모리 내 객체를 다루듯 DB 작업을 수행할 수 있습니다.
ORM은 단순히 편리함을 넘어서, 유지보수성과 재사용성, 보안성까지 함께 높여줍니다.
- SQL 문법을 몰라도 DB 조작이 가능해요
- DB 변경이 생겨도 코드 수정 최소화
- 보안상 SQL 인젝션 위험이 줄어듭니다
SQLAlchemy란?
SQLAlchemy
는 파이썬에서 가장 널리 쓰이는 ORM 프레임워크입니다.
SQL을 완전히 추상화하여 객체 기반으로 DB 작업을 할 수 있게 도와주죠.
특히 다양한 DBMS(예: MySQL, PostgreSQL, SQLite, Oracle 등)를 지원하여 확장성 면에서도 매우 강력합니다.
Flask에서는 Flask-SQLAlchemy
라는 확장 라이브러리를 통해 SQLAlchemy를 더 쉽고 간편하게 사용할 수 있어요.
SQLAlchemy의 핵심 특징
특징 | 설명 |
---|---|
ORM + Core 지원 | ORM 방식과 SQL 직접 작성 방식 모두 지원 |
다양한 DB 지원 | SQLite, MySQL, PostgreSQL 등 거의 모든 RDBMS 사용 가능 |
모델 클래스 매핑 | 파이썬 클래스와 DB 테이블 자동 매핑 |
세션 기반 트랜잭션 | 세션을 통한 트랜잭션 관리로 안전한 작업 가능 |
실습에서는 SQLite를 사용해볼 거예요.
설치가 필요 없고 파일 기반으로 바로 실행되니까 입문자에게 최적이거든요!
2. Flask-SQLAlchemy 설정 방법 ⚙️
ORM 개념과 SQLAlchemy에 대해 이해했다면, 이제 실전입니다!
Flask 애플리케이션에서 Flask-SQLAlchemy를 설정하고 SQLite와 연결해 보겠습니다.
1️⃣ Flask-SQLAlchemy 설치하기
pip install flask flask_sqlalchemy
Flask는 이미 설치되어 있다고 가정하고, flask_sqlalchemy
만 설치하면 준비 완료입니다!
2️⃣ 데이터베이스 구성 설정
Flask 앱에서 SQLAlchemy를 사용하려면, 먼저 DB URI를 설정해야 합니다.
이번 실습에서는 SQLite를 사용하므로 다음과 같은 설정이 필요합니다:
# app.py 또는 config.py 파일 내
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///board.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
-
sqlite:///board.db
: 현재 프로젝트 폴더에 board.db 파일 생성 -
SQLALCHEMY_TRACK_MODIFICATIONS
: 변경 추적 기능 비활성화 (경고 방지)
3️⃣ SQLAlchemy 초기화
설정을 마쳤다면 Flask 애플리케이션에 SQLAlchemy를 초기화해야 합니다.
SQLAlchemy
객체를 생성한 후 Flask 앱과 연결하는 방식으로 진행합니다.
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///board.db'
# MySQL 연결 예시 (사용 시 주석 해제)
# app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://사용자이름:비밀번호@호스트주소:포트/데이터베이스이름'
# 예시: app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:password@localhost:3306/board_db'
# MariaDB 연결 예시 (사용 시 주석 해제)
# app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://사용자이름:비밀번호@호스트주소:포트/데이터베이스이름'
# 예시: app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:password@localhost:3306/board_db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
MySQL이나 MariaDB를 Flask + SQLAlchemy로 연결할 때는 pymysql 또는 mysqlclient 같은 DB 드라이버가 필수입니다.
SQLAlchemy는 ORM이지만, 실제 DB와 통신은 Python용 DB 드라이버가 처리합니다. 즉,
- SQLAlchemy는 DB 쿼리를 객체화하고,
- pymysql 같은 드라이버가 실제 DB와 연결해주는 역할을 합니다.
✅ MySQL / MariaDB에서 가능한 드라이버
드라이버 | URI 접두어 | 설치 방법 | 특징 |
pymysql | mysql+pymysql:// | pip install pymysql | Pure Python, 호환성 높음 |
mysqlclient | mysql+mysqldb:// | pip install mysqlclient | C기반, 속도 빠름 |
asyncmy | mysql+asyncmy:// | pip install asyncmy | 비동기 FastAPI 등에서 활용 |
이렇게 하면 이후에 정의할 모델 클래스들이 자동으로 앱과 연결되어 DB와 상호작용하게 됩니다.
이제 준비가 끝났어요!
다음 단계에서는 실제로 게시글(Post) 모델을 정의하고 테이블과 매핑하는 과정을 배워볼게요.
3. 데이터 모델 정의와 테이블 매핑 📄
이제 본격적으로 ORM의 핵심 기능인 데이터 모델 정의에 들어갑니다.
여기서는 게시판의 핵심 데이터인 게시글을 관리하는 Post
모델을 만들고, 이 모델이 데이터베이스의 테이블과 어떻게 연결되는지를 알아볼 거예요.
📌 모델 클래스 만들기
SQLAlchemy에서는 DB 테이블을 Python 클래스 형태로 정의합니다.
모델 클래스는 db.Model
을 상속하며, 클래스 변수로 각 필드를 정의합니다.
예를 들어 게시글(Post) 모델은 다음과 같이 만들 수 있어요:
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
db = SQLAlchemy()
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
content = db.Column(db.Text, nullable=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
-
id
: 기본 키(PK), 자동 증가 정수 -
title
: 게시글 제목, 최대 100자, 필수 입력 -
content
: 본문 내용, 긴 텍스트 가능, 필수 입력 -
created_at
: 글 생성 시간, 자동으로 현재 시간 저장
🧩 선택: 사용자 모델과 관계 설정
시간 관계상 본 과정에서는 인증 기능을 구현하지 않지만, 관계형 DB에서는 모델 간 연결도 아주 중요합니다.
예를 들어 User와 Post 모델을 연결하면 다음과 같은 식으로 구성할 수 있어요.
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
content = db.Column(db.Text, nullable=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
user = db.relationship('User', backref='posts')
ForeignKey
와 relationship
을 통해 일대다 관계를 명시할 수 있고,
이를 통해 ORM에서 연관 데이터를 자연스럽게 다룰 수 있어요.
이제 모델도 정의했으니, 다음 단계에서는 데이터베이스에 테이블을 실제로 생성하고 마이그레이션 도구를 통해 구조를 관리하는 방법을 배워볼게요.
4. 모델 간의 관계 설정하기 🔗
ORM의 진짜 강점은 복잡한 테이블 간 관계를 객체 지향적으로 관리할 수 있다는 점이에요.
특히 게시판처럼 게시글과 사용자, 댓글 등이 연결된 구조에서는 ForeignKey
와 relationship
기능이 아주 유용합니다.
🔐 관계형 데이터베이스의 기본
관계형 데이터베이스에서는 여러 테이블 간에 관계를 설정해 데이터 중복을 줄이고, 데이터 무결성을 유지할 수 있습니다.
대표적인 관계는 다음과 같아요.
관계 유형 | 예시 |
---|---|
일대일 (One-to-One) | User ↔ Profile |
일대다 (One-to-Many) | User → Post |
다대다 (Many-to-Many) | Post ↔ Tag |
👥 User ↔ Post 관계 구현 예제
이번 예시에서는 한 명의 유저(User)가 여러 개의 게시글(Post)을 작성할 수 있는 일대다(1:N) 관계를 설정해봅니다.
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
content = db.Column(db.Text, nullable=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
user = db.relationship('User', backref='posts')
-
user_id
: 외래 키(ForeignKey)로 User 테이블의 id와 연결 -
relationship
: Post 인스턴스에서 user 접근, User 인스턴스에서 posts 접근 가능
이제 한 유저가 작성한 모든 게시글을 user.posts
로 가져올 수 있고, 게시글에서 작성자를 post.user
로 확인할 수 있어요. 정말 직관적이지 않나요?
다음 단계에서는 이렇게 정의한 모델을 기반으로 실제 DB에 테이블을 생성하고 Flask-Migrate
로 스키마 변경을 관리하는 방법을 알아보겠습니다.
5. 마이그레이션 도구로 테이블 관리하기 🔄
ORM을 사용해서 모델을 정의했으면, 그걸 기반으로 실제 데이터베이스 테이블을 만드는 작업이 필요합니다.
Flask에서는 db.create_all()
을 통해 간단하게 테이블을 생성할 수 있어요.
하지만 실전 개발에서는 마이그레이션 도구를 사용하는 게 더 안전하고 유연합니다.
🛠 db.create_all()으로 초기 테이블 만들기
db.create_all()
은 개발 초기 한 번만 사용하는 테이블 생성 함수입니다.
모델 정의가 끝난 후 다음 코드를 실행하면 해당 테이블이 SQLite에 생성됩니다.
from your_app_name import db
db.create_all()
하지만 테이블 구조가 바뀔 때마다 다시 DB를 지우고 만들 순 없잖아요? 그래서 Flask-Migrate를 사용하는 겁니다.
🧬 Flask-Migrate로 안전하게 관리하기
Flask-Migrate
는 SQLAlchemy 기반 모델의 변경 사항을 추적하고,
DDL(SQL 명령어) 형태로 자동 변환해서 DB에 적용해주는 도구입니다.
Alembic이라는 강력한 마이그레이션 툴 위에 구축되어 있어요.
설치 및 설정
pip install flask-migrate
from flask_migrate import Migrate
migrate = Migrate(app, db)
이제 커맨드라인 명령을 통해 마이그레이션을 생성하고 적용할 수 있어요.
마이그레이션 명령어 모음
명령어 | 설명 |
---|---|
flask db init | 마이그레이션 폴더 초기화 |
flask db migrate -m "Initial migration" | 모델 변경사항을 감지해 마이그레이션 파일 생성 |
flask db upgrade | 실제 DB에 변경사항 반영 |
upgrade
명령이 완료되면 DB에 posts, users 등 테이블이 생성되어 있을 거예요.
직접 DB 파일을 열어보면 더욱 실감 나겠죠?
이제 테이블도 준비 완료!
다음은 이 모델과 테이블을 실제로 다뤄보는 실습 시간입니다.
데이터를 생성하고 저장하고, 다시 불러오는 전 과정을 직접 해볼 거예요.
6. 실습: 데이터 생성, 저장, 조회 🧪
드디어 지금까지 준비한 모델과 테이블을 바탕으로 실제 데이터를 생성하고 조회해볼 시간입니다.
이번 실습에서는 Flask Shell을 활용해 ORM의 기본 동작을 직접 체험해 볼 거예요.
📥 Flask Shell 실행하기
터미널에서 아래 명령어를 입력하면 Flask 앱의 컨텍스트에서 ORM 객체를 바로 사용할 수 있습니다.
flask shell
그 다음 아래처럼 게시글 데이터를 만들어보고 저장해볼 수 있어요.
>>> from app import db
>>> from models import Post
>>> post = Post(title="첫 번째 글", content="ORM으로 저장된 글입니다!")
>>> db.session.add(post)
>>> db.session.commit()
위 코드로 데이터베이스에 게시글 하나가 저장됩니다.
별도의 SQL 없이도 Python 객체를 통해 저장할 수 있는 게 ORM의 묘미죠!
🔍 저장된 게시글 조회하기
조회는 더 간단해요.
query
속성을 사용하면 모든 데이터를 불러오거나, 조건을 걸어 하나만 찾을 수도 있죠.
>>> Post.query.all()
>>> Post.query.filter_by(title="첫 번째 글").first()
-
all()
: 전체 데이터 리스트 조회 -
filter_by()
: 조건 검색 (WHERE 절)
📤 데이터를 삭제하거나 수정하려면?
삭제와 수정도 역시 객체 기반으로 처리할 수 있습니다.
SQL 없이도 데이터를 조작할 수 있으니 정말 직관적이에요.
>>> post = Post.query.get(1)
>>> post.title = "제목 수정됨"
>>> db.session.commit()
>>> db.session.delete(post)
>>> db.session.commit()
정말 쉽죠?
SQL이 필요 없는 이 간편함, ORM을 배우는 가장 큰 이유라고 해도 과언이 아닙니다.
이제 Flask와 ORM, 그리고 SQLite를 활용해서 기본적인 CRUD(생성, 조회, 수정, 삭제) 작업을 모두 수행할 수 있게 되었어요!
이걸 바탕으로 다음 시간에는 뷰 함수와 연결된 게시판 기능을 구현하게 될 거예요.
마무리 🎯
지금까지 Flask 애플리케이션에서 ORM을 사용해 데이터베이스와 연동하는 과정을 처음부터 끝까지 살펴봤습니다.
ORM의 개념 이해부터 SQLAlchemy 설치, 모델 정의, 관계 설정, 마이그레이션, 그리고 실전 테스트까지...
꽤 많은 걸 함께 해봤네요.
SQL을 몰라도 객체 지향적으로 DB를 다룰 수 있다는 점, 그리고 마치 파이썬 코드만으로 모든 데이터를 조작할 수 있다는 게 ORM의 가장 큰 장점이에요.
이제 여러분은 Flask에서 SQLite를 활용해 동적인 데이터를 저장하고, 불러오고, 수정하고, 삭제할 수 있는 기반을 갖췄어요.
다음 단계에서는 이 데이터들을 기반으로 사용자에게 보여주는 인터페이스,
즉 뷰 함수와 템플릿을 통해 웹페이지에서 게시글 목록과 내용을 직접 확인하고 조작하는 방법을 배울 거예요.
여기까지 오신 여러분, 정말 고생 많으셨어요.
직접 코드를 실행하고 테스트해보면서 익히면 훨씬 더 오래 기억에 남을 거예요. 그럼 다음 단계에서 다시 만나요!