SQLAlchemy 란?
SQLAlchemy는 파이썬 데이터베이스 ORM(Object Realtaional Mapping) 라이브러리
Python 코드를 이용해 직관적으로 DB에 대한 CRUD 를 조작 하고, 직관성 높은 코드로 개발 가능
SQLAlchemy 기본 객체
1. engine
- 데이터베이스와의 연결을 관리 (URL 형식의 DB 접근 주소를 필요로 함 (create_engine)
from sqlalchemy import create_engine
# 1. engine 생성
engine = create_engine('mysql+pymysql://<USERNAME>:<PASSWORD>@{HOST}:{PORT}/<DBNAME>'
echo=True,
pool_size=2,
pool_recycle=3600,
max_overflow=0,
pool_timeout=3,
isoloation_level='READ UNCOMMITTED'
)
create_engine
- echo : log 기록
- pool_size : 연결 풀 내에서 동시에 유지할 연결의 최대 수 (0: 무제한)
- pool_recycle : MySQL/MariaDB의 고정된 기간 동안 유휴 상태였던 연결에 대해 자동 연결 종료 (기본값 8시간) 자동으로 삭제 처리 되려면, 명시적인 값 설정 필요
- max_overflow : 풀에 있는 연결의 최대 추가 갯수
- pool_timeout : 연결 풀에서 연결을 가져오기 위해 대기할 최대 시간
- isolation_level : 트랜잭션 격리 수준 설정
* isolation 관련
- create_engine.isolation_level 의 인수를 통한 설정 방법 외에도
- Connection.execution.options.isolation_level를 통한, 연결 마다의 설정도 가능
- READ COMMITTED, READ UNCOMMITTED, REPEATABLE READ, SERIALIZABLE, AUTOCOMMIT 레벨들이 있음
*engine.dispose()
- engine에서 가진 connection pool 자체를 다 종료한다.
2. Base
- Base 클래스의 역할은 모든 ORM 모델의 기반.
- declarative_base() 함수를 통해 호출하여 생성되며 모든 모델은 이 Base 클래스를 상속 받아야 함
- Base를 상속 받은 각 모델은 테이블의 구조 (이름, 컬럼, 데이터 타입 등) 를 정의함
from sqlalchemy.orm import declarative_base
from sqlalchemy import Column, Integer, String
# 2. Base : 모든 모델의 기본 클래스이다.
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(50), nullable=False)
age = Column(Integer, nullable=False)
3. MetaData
- SQLAlchemy에서 데이터베이스의 스키마(테이블, 컬럼, 인덱스, 제약조건, 관계 등) 정보를 저장하고 관리하는 객체
- Base를 상속받아 생성된 모델들의 정보들을 담고 있음
- Base 클래스가 생성될 때 자동으로 MetaData 객체도 생성되며, 모든 모델 클래스들이 MetaData에 등록됨
- 이를 통해 전체 데이터베이스 구조를 관리할 수 있게 됩니다.
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
# 2. Base : 모든 모델의 기본 클래스이다.
Base = declarative_base()
# 3.1 Base.metadata : 각 모델에 대한 메타 정보를 담고 있다.
print(Base.metadata.tables) # 테이블 정보 출력
# immutabledict({
# 'users':
# Table('users',
# MetaData(bind=None),
# Column('id', Integer(), table=<users>, primary_key=True, nullable=False),
# Column('name', String(), table=<users>),
# Column('age', Integer(), table=<users>), schema=None)
# })
# 3.2 Base.metadata의 정보를 바탕으로 engine에 연결된 DB에 테이블을 생성한다.
Base.metadata.create_all(engine)
4. sessionmaker, Session
- 세션은 데이터베이스 엔진과 연결되어, 해당 DB의 트랜잭션을 관리 하고, 데이터베이스 간의 변경 사항을 추적하는 중요한 역할
- sessionmaker를 사용해 'session 팩토리' 생성
- 최종 세션 객체 Session()을 생성하고, DB에 대한조회, 삽입, 갱신, 삭제 등을 수행
from sqlalchemy.orm import sessionmaker
# 1. 데이터베이스 엔진 생성
engine = create_engine('sqlite:///example.db')
# 2. Base를 이용한 모델 정의와 3. meta를 이용한 테이블 생성은 생략
# 4.1 sessionmaker를 사용해 세션 팩토리 생성
Session = sessionmaker(bind=engine)
# 4.2 세션 객체 생성 - DB에 대한 쿼리, 삽입, 갱신 등을 수행
session = Session()
5. session의 재사용
- Session은 내부적으로 데이터베이스 연결을 풀(connection pool)에서 가져와 사용하고, 작업이 끝나면 풀에 반환
Session.close() 란
- pool에 있는 세션을 사용하다가, 다시 반환하는 것
- ORM 객체 해제 : 세션이 관리하고 있는 ORM 객체에 대한 "관리 상태"를 해제하여, 세션이 해당 객체의 변경 사항을 추적하지 않음 의미
- 세션 상태 초기화: Session은 내부적으로 사용된 리소스와 캐시를 정리
- session.close()를 하더라도 객체는 여전히 존재하며, 필요할 때 다시 사용 가능
- session.close()를 호출 후 -> 세션 객체를 재사용하여 새 쿼리를 실행하거나 트랜잭션을 시작한다면 -> 세션은 pool에서 새 연결을 가져와 데이터베이스와 통신
즉 세션은 DB와의 연결을 완전히 닫는 것이 아닌 재사용 가능한 상태로 만든다는 것
* 만약 connection pool 까지 종료하려면?
- engine.dispose()
* Q. sqlalchemy에서 세션을 만들고(sessionmaker) 종료(close) 하면 Connection Pool이 줄어드나?
- A. 아니다
예시 코드
# 세션 생성
session = Session()
# 데이터베이스 작업 수행
user = session.query(User).first()
# 세션 닫기
session.close()
# 세션을 다시 사용하여 새 쿼리 수행
another_user = session.query(User).first() # 재사용 가능!
참고 문헌 (블로그)
'DB > Sqlalchemy' 카테고리의 다른 글
[SQLAlchemy] (5-2) DB driver 종류 (postgresql) (1) | 2024.09.18 |
---|---|
[SQLAlchemy] (5-1) DB driver 종류 (mysql/maria) (0) | 2024.09.16 |
[SQLAlchemy] (4) DML 예시 (by sqlalchemy 2.0) (2) | 2024.09.08 |
[SQLAlchemy] (3) 모델 선언 방법 (선언형, 명령형) (1) | 2024.09.08 |
[SQLAlchemy] (2) Core 방식 vs ORM 방식 (1) | 2024.08.25 |