SQLAlchemy
SQLAlchemy란?
SQLAlchemy 공식 문서
보통의 비망록: SQLAlchemy 시작하기
Dork's port: SQLAlchemy 사용하기
- Python에서 사용가능한 ORM(Object-Relational Maping)
- ORM은 말그대로 객체(Object)와 관계(Relation)를 연결해주는 것
- 데이터베이스의 데이터를 ← 매핑 → Object 필드
- SQLAlchemy 객체 관계형 매퍼는 데이터베이스 테이블을 이용해 사용자가 정의한 파이썬 클래스의 메소드와 각각의 행을 나타내는 인스턴스로 표현
- 객체와 각 연관된 행들의 모든 변경점들이 자동으로 동기되어 인스턴스에 반영되며, 그와 동시에 사용자가 정의한 클래스와 각 클래스 사이에 정의된 관계에 대해 쿼리할 수 있는 (Unit of work이라 하는)시스템을 포함하고 있음
- 이 ORM에서 사용하는 SQLAlchemy 표현 언어는 ORM의 구성 방식과도 같음
- SQL 언어 튜토리얼에서는 직접적인 의견을 배제한 채 데이터베이스들의 초기에 어떻게 구성해 나가야 하는지에 대해 설명하는 반면 ORM은 고수준의, 추상적인 패턴의 사용 방식과 그에 따른 표현 언어를 사용하는 방법을 예로 보여줌
- 사용 패턴과 각 표현 언어가 겹쳐지는 동안, 초기와 달리 공통적으로 나타나는 사항에 대해 표면적으로 접근
- 먼저 사용자가 정의한 도메인 모델서부터 기본적인 저장 모델을 새로 갱신하는 것까지의 모든 과정을 일련의 구조와 데이터로 접근하게 해야함
- 또 다른 접근 방식으로는 문자로 된 스키마와 SQL 표현식이 나타내는 투시도로부터 명쾌하게 구성해, 각 개별적인 데이터베이스를 메시지로 사용할 수 있게 해야 함
- 장점
- 객체 지향적인 코드로 비즈니스 로직에 집중 가능
- 재사용 및 유지보수 편리성이 증가
- DBMS에 대한 종속성이 줄어듬
- 단점
- ORM 만으로 서비스를 구현하기 어려움
- 프로시저가 많은 시스템에서는 장점을 가져가기 어려움
사용 방법
버전 확인
import sqlalchemy
print sqlalchemy.__version__
접속
from sqlalchemy import create_engine
engine = create_engine('sqlite:///:memory:', echo=True)
echo
는 로그를 위한 플래그
- 파이썬 표준 logging 모듈 사용
- 순수 SQL 코드를 보여줌
engine
은 선언만 해서 바로 연결되는게 아니라 첫 실행이 될 때 연결
print engine.execute("select 1").scalar()
- ORM을 사용할 때는 위처럼 engine을 직접 이용할 필요는 없음
- 맨 처음 연결 할 때 작성하고 ORM 사용하면 됨
매핑 선언
- ORM에서는 처음에 데이터베이스 테이블을 써먹을 수 있게 설정한 다음 직접 정의한 클래스에 맵핑을 해야함
- SQLAlchemy에서는 두가지가 동시에 이뤄지는데
Declarative
란걸 이용해 클래스를 생성하고 실제 데이터베이스 테이블에 연결
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
- 이렇게 해두면 몇개든 매핑 클래스를 만들 수 있음
- 매핑 클래스 내에서 데이터베이스의 컬럼을 나타내는 Column 클래스, 각 컬럼의 데이터타입을 나타내는 Integer, String 클래스를 불러와야 함
from sqlalchemy import Column, Integer, String
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
fullname = Column(String)
password = Column(String)
def __init__(self, name, fullname, password):
self.name = name
self.fullname = fullname
self.password = password
def __repr__(self):
return "<User('%s', '%s', '%s')>" % (self.name, self.fullname, self.password)
- 위 User 클래스는
__tablename__
에서 정의한 테이블에 맵핑되고 primary key인 id와 name, fullname, password 컬럼을 가짐
- 메소드는 마음껏 만들어도 상관없음
- 파이썬 기본 class와 같음
__init__
와 __repr__
도 생성 가능
- Base를 상속하지만 이는 단지 최소의 설정만 담당
Declarative System
으로 만들어진 이 클래스는 table metadata를 가지게 되는데 이것이 사용자 정의 클래스와 테이블을 연결해주는 기능을 수행
- 예전엔 이 metadata를 만들고 클래스에 맵핑해서 썼는데 그 방식을
Classical Mapping
이라고 함
- 그 예전 방식에서는 Table이라는 데이터 구조와 Mapper 객체로 클래스와 맵핑
User.__table__
User.__mapper__
Declarative
기반 클래스는 모든 Table 객체들을 metadata로 정의해두고 .metadata
속성을 통해 접근할 수 있게 도와줌
- 아직 위의 예제 클래스는 테이블이 생성이 되지 않은 상태인데 metadata를 통해 손쉽게 생성할 수 있도록 도와준다. 테이블을 생성할 때
metadata.create_all()
로 생성할 수 있는데 이 메소드를 호출하면 engine으로 연결된 데이터베이스에 테이블을 생성
Base.metadata.create_all(engine)