home..

Database ORM

영속성

영속성이란 데이터를 생성한 프로그램이 종료되도 데이터가 사라지지 않는 특징을 의미한다. 영속성이 없는 데이터는 메모리에서만 존재하여 프로그램 종료시 증발하게 된다.

메모리 상 데이터를 파일 시스템, RDBMS 등을 활용하여 영구적으로 저장한다. 저장하는 방법은

  1. JDBC
  2. Spring JDBC
  3. Persistence Framework( JPA, Hibernate, Mybatis ) 가 있다.

ORM

ORM( Object Relational Mapping )이란 객체와 관계형 데이터베이스 데이터를 매핑하는 것을 의미한다. 객체 지향의 클래스, RDBMS의 테이블을 사용하여 서로 연결해준다. ORM을 통해 객체 간 관계를 기반으로 SQL를 자동으로 생성하고 일치시킨다. 즉, 객체를 통해 간접적으로 DB 데이터를 다룬다.

장점

Object–relational impedance mismatch

Object–relational impedance mismatch는 객체 모델과 RDBMS가 같은 데이터를 표현하고 다루는 방법에서 발생하는 차이를 의미하는 패러다임의 불일치이다.

참고

https://gmlwjd9405.github.io/2019/02/01/orm.html

Python ORM - sqlalchemy

Mapping Class

SQLAlchemy를 이용하여 파이썬에서 ORM을 작성할 수 있다. 공식 문서에서 예시를 참고하였다.

  1. DB에 연결한다.

from sqlalchemy import create_engine
engine = create_engine('{RDBMS_URL}')
  1. Mapping을 정의한다. DB 테이블과 매핑하여 CRUD를 위한 클래스를 생성한다. 테이블 생성을 위해서는 클래스와 DB를 연결하는 base 클래스를 사용한다.
from datetime import datetime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, DateTime

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    fullname = Column(String)
    nickname = Column(String)

    def __repr__(self):
    return "<User(name='%s', fullname='%s', nickname='%s')>" % (
    ...                             self.name, self.fullname, self.nickname)

  1. Schema를 생성한다.
    Base.metadata.create_all(engine)
    '''
    BEGIN...
    CREATE TABLE users (
     id INTEGER NOT NULL,
     name VARCHAR,
     fullname VARCHAR,
     nickname VARCHAR,
     PRIMARY KEY (id)
    )
    [...] ()
    COMMIT
    '''
    
  2. 매핑 클래서의 인스턴스를 생성한다.
    >>> ed_user = User(name='ed', fullname='Ed Jones', nickname='edsnickname')
    >>> ed_user.name
    'ed'
    >>> ed_user.nickname
    'edsnickname'
    >>> str(ed_user.id)
    'None'
    

Session 활용

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

Objects 추가 및 수정

ed_user = User(name='ed', fullname='Ed Jones', nickname='edsnickname')
session.add(ed_user)

이 시점에서 instance가 pending이라고 할 수 있다. Session은 필요한 순간에 대기 중이던 SQL을flush 를 통해 Ed Jones를 추가한다.

>>> our_user = session.query(User).filter_by(name='ed').first()
>>> our_user
<User(name='ed', fullname='Ed Jones', nickname='edsnickname')>

Session은 map을 통해 생성된 객체와 our_user가 같은 객체임을 식별한다.

>>> ed_user is our_user
True

Reflecting Database Objects

Table object는 database schema에서 정보를 로드할 수 있다(reflection)

>>> messages = Table('messages', meta, autoload_with=engine)
>>> [c.name] for c in messages.columns]
['message_id', 'message_name', 'date']

messages table에 database 정보를 반영한다.

© 2024 Yujin Lee   •  Powered by Soopr   •  Theme  Moonwalk