2025-01-23T11:02:27
This commit is contained in:
154
doc/28_04_sqlqlchemy.md
Normal file
154
doc/28_04_sqlqlchemy.md
Normal file
@@ -0,0 +1,154 @@
|
||||
# SQLAlchemy: 파이썬에서 객체 지향적으로 데이터베이스를 다루는 강력한 도구
|
||||
|
||||
SQLAlchemy는 파이썬에서 데이터베이스를 다루기 위한 강력한 ORM(Object-Relational Mapper) 라이브러리입니다. ORM은 객체 지향 언어의 개념을 사용하여 관계형 데이터베이스를 다루는 방식으로, 개발자들이 SQL 문법을 직접 작성하지 않고도 데이터베이스와 상호 작용할 수 있도록 해줍니다.
|
||||
|
||||
* 다양한 데이터베이스 지원: MySQL, PostgreSQL, SQLite 등 다양한 관계형 데이터베이스를 지원합니다.
|
||||
* 객체-관계 매핑: 파이썬 클래스를 데이터베이스 테이블에 매핑하여 객체 지향적인 방식으로 데이터를 관리합니다.
|
||||
* SQLAlchemy ORM: SQL을 직접 작성하지 않고, 파이썬 객체를 통해 데이터베이스를 조작할 수 있습니다.
|
||||
* SQLAlchemy Core: 저수준 API를 제공하여 복잡한 SQL 쿼리를 직접 작성할 수 있습니다.
|
||||
* 데이터베이스 마이그레이션: 데이터베이스 스키마를 관리하고 변경하는 기능을 제공합니다.
|
||||
|
||||
```python
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy import Column, Integer, String
|
||||
|
||||
# 데이터베이스 연결
|
||||
engine = create_engine('sqlite:///mydatabase.db')
|
||||
Base = declarative_base()
|
||||
|
||||
# User 모델 정의
|
||||
class User(Base):
|
||||
__tablename__ = 'users'
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(String(50), nullable=False)
|
||||
email = Column(String(120), unique=True, nullable=False)
|
||||
|
||||
# 데이터베이스 생성
|
||||
Base.metadata.create_all(engine)
|
||||
|
||||
# Session 생성 (데이터베이스와의 상호작용을 위한 세션)
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
Session = sessionmaker(bind=engine)
|
||||
session = Session()
|
||||
|
||||
# 데이터 추가
|
||||
new_user = User(name='Alice', email='alice@example.com')
|
||||
session.add(new_user)
|
||||
session.commit()
|
||||
|
||||
# 데이터 조회
|
||||
users = session.query(User).all()
|
||||
for user in users:
|
||||
print(user.name, user.email)
|
||||
```
|
||||
|
||||
## 주요 개념
|
||||
* Engine: 데이터베이스에 대한 연결 정보를 담고 있는 객체입니다.
|
||||
* Session: 데이터베이스와의 상호 작용을 위한 세션 객체입니다.
|
||||
* Model: 데이터베이스 테이블에 해당하는 파이썬 클래스입니다.
|
||||
* Query: 데이터베이스에서 데이터를 조회하기 위한 쿼리 객체입니다.
|
||||
|
||||
## 모델
|
||||
### 모델 정의 기본 구조
|
||||
```python
|
||||
from sqlalchemy import Column, Integer, String
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
class User(Base):
|
||||
__tablename__ = 'users'
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(String(50), nullable=False)
|
||||
email = Column(String(120), unique=True, nullable=False)
|
||||
```
|
||||
* Base: 모든 모델 클래스가 상속받는 기본 클래스입니다.
|
||||
* tablename: 데이터베이스 테이블 이름을 지정합니다.
|
||||
* Column: 테이블의 각 열을 정의합니다.
|
||||
* type: 데이터 타입 (Integer, String, Float, DateTime 등)
|
||||
- Integer: 정수형 데이터
|
||||
- String(길이): 문자열 데이터
|
||||
* primary_key: 기본키 설정
|
||||
* nullable: null 허용 여부
|
||||
* unique: 중복 값 허용 여부
|
||||
* index: 인덱스 생성
|
||||
* foreign_key: 외래 키 설정
|
||||
* 그 외 다양한 속성 지원
|
||||
|
||||
### 관계 설정
|
||||
- one-to-one
|
||||
```python
|
||||
user = relationship("User", back_populates="address")
|
||||
```
|
||||
- one-to-many
|
||||
```python
|
||||
orders = relationship("Order", back_populates="user")
|
||||
```
|
||||
- many-to-many
|
||||
```python
|
||||
tags = relationship("Tag", secondary=association_table, back_populates="posts")
|
||||
```
|
||||
### 모델 메타데이터
|
||||
* metadata: 모든 모델에 대한 정보를 담고 있는 객체입니다. create_all() 메서드를 사용하여 데이터베이스에 테이블을 생성합니다.
|
||||
|
||||
```python
|
||||
class Post(Base):
|
||||
__tablename__ = 'posts'
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
title = Column(String(100), nullable=False)
|
||||
content = Column(Text)
|
||||
created_at = Column(DateTime, default=func.now())
|
||||
user_id = Column(Integer, ForeignKey('users.id'))
|
||||
|
||||
user = relationship("User", back_populates="posts")
|
||||
```
|
||||
|
||||
## 쿼리
|
||||
* session.query(모델명): 해당 모델에 대한 쿼리 객체를 생성합니다.
|
||||
|
||||
### 쿼리 수행
|
||||
- 모든 데이터 조회
|
||||
```python
|
||||
results = query.all()
|
||||
```
|
||||
- 첫 번째 데이터 조회
|
||||
```python
|
||||
first_result = query.first()
|
||||
```
|
||||
- 조건에 맞는 데이터 조회
|
||||
```python
|
||||
users = session.query(User).filter(User.name == 'Alice')
|
||||
```
|
||||
- 데이터 정렬
|
||||
```python
|
||||
users = session.query(User).order_by(User.id.desc())
|
||||
```
|
||||
- 데이터 그룹화
|
||||
```python
|
||||
groups = session.query(func.count(User.id), User.city).group_by(User.city)
|
||||
```
|
||||
### 쿼리 메서드
|
||||
* filter(): 조건에 맞는 데이터를 필터링합니다.
|
||||
* order_by(): 데이터를 정렬합니다.
|
||||
* group_by(): 데이터를 그룹화합니다.
|
||||
* limit(): 조회 결과를 제한합니다.
|
||||
* offset(): 조회 시작 위치를 설정합니다.
|
||||
* all(): 모든 결과를 리스트로 반환합니다.
|
||||
* first(): 첫 번째 결과를 반환합니다.
|
||||
* one(): 정확히 하나의 결과를 반환하고, 없거나 여러 개일 경우 예외를 발생시킵니다.
|
||||
|
||||
### 복잡한 쿼리
|
||||
* 조인: 여러 테이블을 연결하여 데이터를 조회합니다.
|
||||
* 서브쿼리: 쿼리 안에 또 다른 쿼리를 포함하여 복잡한 조건을 설정합니다.
|
||||
* 함수: func를 사용하여 SQL 함수를 호출합니다.
|
||||
|
||||
```python
|
||||
from sqlalchemy import func
|
||||
|
||||
# 특정 도시에 거주하는 사용자의 평균 나이
|
||||
result = session.query(func.avg(User.age)).filter(User.city == 'Seoul').scalar()
|
||||
```
|
||||
Reference in New Issue
Block a user