전공영역 공부 기록

SQL Achemy 2편 - ORM

악분 2021. 8. 19. 14:45
반응형

이 글은 1편에 이어 SQL Alchemy를 이용해서 ORM을 사용하는 방법을 다룹니다.

 

영상으로도 만나볼수 있습니다.https://youtu.be/kS1J_QwnIgs

 

1. ORM 이란?

ORM(Object Relational Mapper)은 쿼리를 객체처럼 다루는 것을 의미합니다. 객체를 쿼리로 매핑하다는 의미에서 매퍼(Mapper)라는 단어가 포함되어 있는 것 같습니다.
기존에 쿼리문을 직접 작성 sql alchemy에게 쿼리실행을 맡겼었습니다. ORM은 쿼리 대신 객체와 관련된 작업을 넘겨주면 sql alchemy가 객체를 쿼리문으로 변경해서 실행하게 됩니다.

그림1 쿼리 실행과 ORM비교


예제를 보시면 무슨 말인지 이해가실겁니다. 시리즈 1편에서 insert 쿼리를 예로 들어보겠습니다. 1편에서 사용했던 insert 쿼리문은 아래와 같습니다.

engine.execute('INSERT INTO "EX1" ' '(id, name) ' 'VALUES (1, "raw")')


sql alchmey 엔진을 사용해서 쿼리문을 실행했었는데요. 이것을 ORM으로 변경해서 쿼리문을 실행한다면 아래와 같습니다. demo라는 객체를 생성해서 sql alchemy에게 해당 객체를 쿼리문으로 실행하라고 던지는겁니다.

demo = Demo(name="hello", password="world") session.add(demo) session.commit()

 

2. sqlalchemy이 ORM을 다루는 원리

sqlalchemy는 proxy object를 사용해서 ORM을 관리합니다.
sqlalchemy는 개발자가 요청한 ORM을 데이터베이스에 바로 반영하지 않습니다. proxy object라고 불리는 중간 메모리 공간에 ORM을 먼저 저장합니다. 그리고 cocmmit메소드가 호출되면 그때서야 proxy object에 저장된 ORM을 데이터베이스에 반영합니다. proxy object를 sqlalchemy에서는 Session이라고 부릅니다.

그림2 proxy object

 

3. 예제 실습

소스코드 링크: https://github.com/choisungwook/fastapid-example/blob/main/SQLAlchemy_basic/ORM.ipynb

 

3.1 엔진 생성

쿼리를 실행할 때 엔진을 사용했던 것처럼 ORM역시 엔진을 사용합니다. 이 글에서는 sqlite를 사용하고 db파일 이름은 example.db를 사용합니다. echo=True옵션은 ORM을 쿼리로 변경하고 실행할 때, 실제로 어떤 쿼리가 실행되었는지 로그를 출력하는 옵션입니다.

from sqlalchemy import create_engine engine = create_engine('sqlite:///example.db', echo=True)

 

3.2 세션 생성

ORM을 저장하는 proxy object session을 생성하는 단계입니다. session은 sessionmaker가 생성해줍니다. 주목할 점은 session을 생성할 때 engine을 연동해준다는 것입니다.

from sqlalchemy.orm import sessionmaker Session = sessionmaker(bind=engine) session = Session()

 

3.3 ORM 관리 객체 생성

ORM을 생성하기 위해 ORM관리 객체를 생성해야 합니다.

from sqlalchemy.ext.declarative import declarative_base Base = declarative_base()

 

3.4 ORM(또는 Entity) 생성

3.3챕터에서 만든 ORM객체를 상속해서 ORM을 만들 수 있습니다. 데이터베이스에 익숙하다면 설명없이 바로 이해하실 수 있을 겁니다. 칼럼은 클래스 변수로 관리됩니다.

from sqlalchemy import Column, Integer, String class Demo(Base): __tablename__ = 'demos' id = Column(Integer, primary_key=True) name = Column(String) password = Column(String)


Demo ORM은 아직 ORM Metadata로만 등록된 상태입니다. 아직 데이터베이스 테이블로 생성되지 않은 상태이죠.

그림3 Metadata


3.5 ORM을 이용하여 테이블 생성
metadata에 등록된 테이블을 실제 테이블로 생성하기 위해서는 create_all함수를 실행해야 합니다.

Base.metadata.create_all(engine)


create_all함수 실행결과를 보면 맨 마지막 로그에 COMMIT이 보입니다. ORM 쿼리 실행을 반영하기 위해서는 항상 마지막에 COMMIT이 실행됩니다.

그림4 create_all함수 실행 로그


sqlite viewer에서 테이블 목록을 확인하면 demos테이블이 잘 보입니다.

그림5 테이블 생성확인

 

3.5 행(row) 추가

생성한 테이블에 행을 추가 과정은 3단계로 진행됩니다.

  1. 생성한 ORM를 이용해서 객체를 생성한다.
  2. session.add함수로 ORM을 session에 등록한다
  3. session.commit함수를 호출해서 쿼리를 실행한다.


객체를 생성하는 방법은 간단합니다. [그림 3]에서 정의한 ORM을 이용해서 객체를 생성하면됩니다. 객체 생성 시 파라미터를 전달하면 칼럼 초기값을 설정할 수 있습니다.

demo = Demo(name="hello", password="world")


생성한 객체를 쿼리로 실행하기 위해서는 session에 등록하는 과정입니다. [그림 2]에서 설명한 것처럼 session에 등록된 ORM이 commit함수가 실행될 때 쿼리로 변환되어 실행됩니다. session.add함수를 사용해서 session에 ORM을 등록할 수 있습니다.

session.add(demo)


session.commit함수를 사용하면 session에 저장된 ORM이 데이터베이스에 반영됩니다.
session.commit을 사용하지 않으면 session에만 저장되어 있습니다. 그리고 애플리케이션이 꺼진다면 session도 메모리이기 때문에 저장된 ORM은 삭제됩니다.

session.commit()

그림6 session commit 실행결과


sqlite viewer로 확인하면 테이블에 hello world행이 추가된 것을 확인할 수 있습니다.

그림6 행추가 확인

반응형