플라스크로 나만의 웹 페이지 만들기-06

Intro


이 포스트는 플라스크로 나만의 웹 페이지 만들기 - 05 에 의존합니다. 이전 포스트를 먼저 보시는걸 추천합니다.


데이터베이스 오퍼레이션


쉽게는 파이썬 쉘로 작업하는게 좋지만 파일로 만들어서 실행시켜도 무방하다.

우선 DB에 접속한다.

메모리에서만 사용하는 sqlite 데이터베이스를 사용한다.

from sqlalchemy import create_engine
engin = create_engine('sqlite:///:memory:', echo=True)


echo는 로그를 위한 플래그.

맨처음 DB에 연결할때 작성하면 된다.


매핑


ORM 에서는

  1. 처음 테이블을 사용할 수 있게 설정한다음
  2. 정의한 클래스에 직접 매핑을 한다.

sqlalchemy에서는 두가지가 동시에 이루어진다. Declarative를 이용하여 클래스를 생성하고 실제 DB 테이블에 연결을 한다.

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처럼 마음껏 만들어도 무방하다.


매핑된 클래스로 인스턴스 만들기

ad_user = User('kangju', 'heo', '1234')
ad_user.name        # 'kangju'
ad_user.password    # '1234'
str(ad_user.id)     # 'None'


id는 __init__()에서 정의하지 않았지만 매핑을 해뒀기때문에 None으로 존재한다.

위 값에서 heo를 DB에 넣기 전 까지는 id값이 None 이다.


세션 만들기


데이터베이스에 대한 변경 사항은 데이터베이스 세션(Session)을 통해 관리되는데, flask-sqlalchemy에서는 db.session으로 제공한다.

데이터베이스 작성을 위해 오브젝트를 준비하기 위해서는 오브젝트가 세션에 추가되어야 한다.


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


이렇게 작성한 Session클래스는 새 객체를 만들어서 데이터베이스와 연결이 된다. 이제부터 언제든 데이터베이스와 대화가 필요할 때 session을 불러서 쓰면된다.


새 객체 추가하기


ad_user = User('kangju', 'heo', '1234')
session.add(ad_user)


여기서는 실제로 데이터베이스에 추가된게 아니라 pending인 상태다. 입력은 flush라는 과정을 통해 입력된다.

만약 DB에 쿼리를 날리면 모든 pending된 정보는 flush 되고 접근 가능한 상태가 된다.(이때도 정장된 상태는 아니다. 여전히 pending. 단지 접근이 가능해 지는 것 뿐.)

add_all()로 데이터를 추가 해 보자.

session.add_all([
    User('wendy', 'Wendy Williams', 'foobar'),
    User('mary', 'Mary Contrary', 'xxg527'),
    User('fred', 'Fred Flinstone', 'blar')])


비밀번호도 바꿔보고.

ad_user.password = 'test1234'


Session은 계속 연결되어있는 객체를 보고있기때문에 위처럼 데이터를 추가하거나 수정한 사실을 알고있다.

데이터베이스에 오브젝트를 작성하기 위해서는 세션이 commit() 메소드를 호출하여 커밋해야한다. 커밋은 모든 변경, 추가 사항들을 반영하고 connection pool을 반환한 뒤 모든 객체들을 업데이트 한다.

db.session.commit()

쿼리 보내기


Query객체는 session에서 query()메소드로 생성한다.

for instance in session.query(User).order_by(User.id):
    print instance.name, instance.fullname


Query는 keyedTuple 클래스를 통해 튜플로 반환하는데 이걸 일반적인 파이썬 클래스로 활용할 수 있다. 각각 저장된 값들은 클래스 이름이나 속성 이름과 동일하다.

결과물을 필터링 할 때는 filter_by()를 쓰면 된다.

for name in session.query(User.name).filter_by(fullname='heo'):
    print name


변경후 commit()하는것 잊지말자.


참고 및 출처

Haruair님 블로그