본문 바로가기
AI 웹개발반/Python, Django

[Django] JSONfield

by 째깍단 2023. 7. 4.

 

이 글은 DB에 자료형을 넣어주고싶은 욕망에서 시작되었다..!

 

기초적인 ai챗봇을 만들면서 장고의 model field, JSONfield 을 사용해보았다

 

 

 

 

 

⭐️ DB 테이블에 list를 넣어주고 싶었던 이유 :

 

1)  일단 장고니까!  list를 넣는 것이 가능할 것 같았다.

     마침 이전에 찾아보았던 정보에 list를 불러온 예시도 발견하여서 무언가 방법이 있으리라 생각했다.

 

https://www.django-rest-framework.org/api-guide/relations/#hyperlinkedrelatedfield

 

 

 

2) 채팅 로그처럼(채팅은 아니지만) 이전 대화를 프론트에서 띄워주는 기능도 함께 넣어주고 싶었기때문에

     ai와 user가 넣은 Input 정보를 저장하고자 했다.

     그리고 유저 한 명 마다 너무 많은 채팅 데이터를 남기지 않도록 DB 내의 데이터를 제한해주고 싶었다.

     list는 알고리즘을 풀면서 많이 접해본 편이어서 잘 조작하면 제한된 데이터를 저장해줄 수 있을 것 같았다.

 

 

 

3) openai 를 공부하면서 {'role' : 'assistant'}에 대해 알게되었는데,

    더 자연스러운 대화를 위해 assistant에 ai가 이전에 출력한 prompt를 입력해주고 싶었다.

    (assistant = '도우미' 라는 말로 이전 대화를 챗gpt에게 넣어주어 대화의 기반을 약간이나마 마련해주는 힌트 같은 것.)

   

 

 


 

 

JSONfield

 

JSONfield는 입력한 데이터를 DB에 json형태로 저장해주는 장고 기본제공 모델 필드

response를 보낼 때 매우 편리하게 느껴질 듯하다:)

 

더보기

쉽게 말하자면 data를 내부에 자료형이나 사전형으로  저장할 수 있도록 해주는 필드!

 

아래는 공식문서의 예시. 

아래와 같이 데이터의 내부에 추가적인 데이터를 형성하여 key값 등으로 필요한 정보를 불러낼 수 있다.

 

#기본적인 사용
>>> Dog.objects.create(
...     name="Rufus",
...     data={
...         "breed": "labrador",
...         "owner": {
...             "name": "Bob",
...             "other_pets": [
...                 {
...                     "name": "Fishy",
...                 }
...             ],
...         },
...     },
... )
<Dog: Rufus>
>>> Dog.objects.create(name="Meg", data={"breed": "collie", "owner": None})
<Dog: Meg>
>>> Dog.objects.filter(data__breed="collie")
<QuerySet [<Dog: Meg>]>

#연결된 정보 불러내기
>>> Dog.objects.filter(data__owner__name="Bob")
<QuerySet [<Dog: Rufus>]>

 

 

 

 

현재 4.2버전에서는 KT 라는 새로운 기능이 추가되었다!

JSON field에 한해 사용할 수 있는 것 같지만 간단하고 유용한 기능으로 보인다. 머리 속에 저장저장

 

>>> from django.db.models.fields.json import KT
>>> Dog.objects.create(
...     name="Shep",
...     data={
...         "owner": {"name": "Bob"},
...         "breed": ["collie", "lhasa apso"],
...     },
... )
<Dog: Shep>
>>> Dogs.objects.annotate(
...     first_breed=KT("data__breed__1"), owner_name=KT("data__owner__name")

 

 

 

 

class JSONField(encoder=Nonedecoder=None**options)

인자로는 encoder, decoder를 받고, 옵션도 설정할 수 있다

 

 

 

 

기본적으로  MariaDB, MySQL, Oracle, PostgreSQL  SQLite 를 지원하기때문에 범용성이 높다!!

 

찾아본바 postgresql을 사용할 경우 ArrayField를 사용하면 된다고 하지만,

아직 배포 전이라 다른 DB를 사용할 수도 있었기 때문에 JSONfield를 활용하였다.

 

 

 

 

공식문서에서는 default value를 사전형, 자료형 처럼 mutable하게 설정할 수 있다고 하지만

default옵션을 [] 혹은 {}로 설정하면 warning이 뜬다

 

 

 

 

 

그리고  이미 저장된 형식이 자료형이어도 serializer를 사용해 저장할때 string을 request.data로 넣어줄 경우

 

해당 string만 저장해버리고 다른 정보를 싹 날려버리는(!) 사고가 발생하니 주의하자

 

 

 

 

 

jsonfield를 활용해 채팅 데이터를 저장한 예제

https://diane073.tistory.com/151

 

[AI] Chatgpt-3.5 와 DRF로 챗봇 만들기 - 2 -

JSONfield에 관해서는 이전 글 참고 : https://diane073.tistory.com/150 JSONfield를 list형태로 만들기 위해서는 처음 입력할때 list형태로 저장해 줄 것임을 명확히 알려주어야한다. !! request data를 그냥 넣으면

diane073.tistory.com

 

 

 

 

[공식문서]

JSONfield

https://docs.djangoproject.com/en/4.2/ref/models/fields/#django.db.models.JSONField

JSONfield 쿼리하기

https://docs.djangoproject.com/en/4.2/topics/db/queries/#querying-jsonfield