본문으로 바로가기
반응형

1. 개요

PostgreSQL은 JSON타입의 컬럼을 지원한다. NoSQL처럼 Schemaless 형태의 데이터를 저장할 필요성이 있지만, NoSQL로 가기는 조금 꺼려지는 경우에 사용하기 용이할것같다. SQLAlchemy에서 JSON타입의 컬럼을 다루다보면 이상하게도 값이 업데이트되지 않는 현상이 발생한다. 예를 들어서,


class Order(Base):
__tablename__ = 'orders'

id = Column(Integer, primary_key=True, autoincrement=True)
info = Column(JSONB)

위와 같은 테이블이 있다고 가정하자. info같은 경우 JSON타입으로 되어있는데 만약 값을 바꾸고 싶다면 일반적으로 아래와 같은 코드를 사용할 것이다.


order = session.query(Order).get(1)
order.info['new'] = 'data'
session.add(order)
session.commit()

위 코드를 실제로 실행시켜보면 아무런 오류가 발생하지 않지만 실제로 데이터베이스에는 반영이 되지 않는다. 그 이유에 대해서 찾아보니 기본적으로 SQLAlchemy에서 JSON컬럼의 타입은 Immutable하다고 한다. 그렇기 때문에 직접적으로 데이터를 수정해주려 하면 반영이 되지 않는 것이다. 여기에는 2가지 해결 방법이 존재한다.


- flag_modified 이용

from sqlalchemy.orm.attributes import flag_modified


order = session.query(Order).get(1)
order.info['new'] = 'data'
flag_modified(order, 'info')

session.add(order)
session.commit()


- MutableDict 이용

from sqlalchemy.ext.mutable import MutableDict


class Order(Base):
__tablename__ = 'orders'

id = Column(Integer, primary_key=True, autoincrement=True)
info = Column(MutableDict.as_mutable(JSONB))

매 저장마다 flag_modified() 함수를 적용하는것이 조금 번거롭다고 느껴진다면 위처럼 컬럼 정의 시 Mutable 형태로 만들어줄수도 있다.

반응형