programing

Peeee 모델에서 JSON으로

goodcopy 2023. 3. 19. 21:06
반응형

Peeee 모델에서 JSON으로

Peeee를 ORM으로 사용하여 API를 만들고 있는데, Peeee 모델 객체를 JSON 객체로 변환하여 사용자에게 전송할 수 있는 기능이 필요합니다.이걸 할 수 있는 좋은 방법을 아는 사람?

Peeee는model_to_dict그리고.dict_to_model의 조력자playhouse.shortcuts확장 모듈

이것들은 다음과 같이 사용할 수 있습니다.

from playhouse.shortcuts import model_to_dict, dict_to_model

user_obj = User.select().where(User.username == 'charlie').get()
json_data = json.dumps(model_to_dict(user_obj))

또, 주의해 주세요.model_to_dict()는 관련 모델을 통해 반복되고, 백소싱된 모델을 포함하며, 특정 필드가 시리얼화되지 않도록 제외할 수 있습니다.

싱글 페치가 되었을 때

user = User.select().where(User.id == 1).get()
model_to_dict(user)  #to Dict

다중 가져오기 시

users = list(User.select().where(User.name ** 'a%').dicts()) 

또한 dict로 모델을 가져온 다음 올바른 필드 유형(bool, int, float 등)을 가진 json으로 변환할 수 있습니다.

import peewee
import json
from bson import json_util
from datetime import datetime

class User(peewee.Model):
    email = CharField()
    status = BooleanField(default=True)
    firstname = CharField()
    lastname = CharField()
    age = IntegerField()
    created = DateTimeField(default=datetime.now())
    class Meta:
        database = db

user = User.select().dicts().get()
print json.dumps(user, default=json_util.default)

다음과 같은 문제를 안고 계신 분들을 위해TypeError: Object of type date is not JSON serializable(Python 3.8.2에서 테스트 완료).

from playhouse.shortcuts import model_to_dict
import json

def print_model(model):
    print(json.dumps(model_to_dict(model), indent=4, sort_keys=True, default=str))

def print_models(models):
    print(json.dumps(list(models.dicts()), indent=4, sort_keys=True, default=str))

사용방법 1 - 단일 모델

for person in Person.select():
    print_model(person)

사용방법 2 - 많은 모델

print_models(Person.select())

같은 문제가 발생하여 자동으로 시리얼화할 수 없는 JSON 유형의 파서 확장을 정의하게 되었습니다.데이터 표시는 문자열로 해도 괜찮습니다(데이터 타입은 다를 수 있습니다만, 부동 소수점에서의 근사에 주의해 주세요).

다음 예제에서는 이 파일을json_serialize.py내부utils폴더:

from decimal import Decimal
import datetime

try:
    import uuid
    _use_uuid = True
except ImportError:
    _use_uuid = False

datetime_format = "%Y/%m/%d %H:%M:%S"
date_format = "%Y/%m/%d"
time_format = "%H:%M:%S"


def set_datetime_format(fmt_string):
    datetime_format = fmt_string


def set_date_format(fmt_string):
    date_format = fmt_string


def set_time_format(fmt_string):
    time_format = fmt_string


def more(obj):
    if isinstance(obj, Decimal):
        return str(obj)

    if isinstance(obj, datetime.datetime):
        return obj.strftime(datetime_format)

    if isinstance(obj, datetime.date):
        return obj.strftime(date_format)

    if isinstance(obj, datetime.time):
        return obj.strftime(time_format)

    if _use_uuid and isinstance(obj, uuid.UUID):
        return str(obj.db_value())

    raise TypeError("%r is not JSON serializable" % obj)

그리고 내 앱에서:

import json
from utils import json_serialize

...


json.dumps(model_to_dict(User.get()), default=json_serialize.more)

추가만을 위해 편집: 이것은 매우 많은 부분에서 영감을 받았습니다.json_utils.defaultmongodb에서 볼 수 있는 모듈이지만 주로 에 의존합니다.jsonmongodb 자체 bson/json_suns 모듈을 Import할 필요가 없습니다.

보통 앱이 새로운 타입을 지원하도록 업데이트 합니다.TypeError연재할 수 없는 타입을 발견했기 때문입니다.

저는 보통 코드 내부 동작에 대한 최대한의 보안과 이해를 위해 모델을 dit 및 dit to model functions에 구현합니다.피위는 마술을 많이 부리는데 당신은 그걸 통제하고 싶어해요

필드를 반복하지 않고 명시적으로 지정해야 하는 가장 명백한 이유는 보안상의 고려 사항입니다.모든 필드가 사용자에게 노출되는 것은 아니며, REST API를 구현하려면 이 기능이 필요하다고 생각합니다.

따라서 다음과 같은 작업을 수행해야 합니다.

class UserData(db.Model):
    user = db.ForeignKeyField(User)
    data = db.CharField()

    def serialize():
        # front end does not need user ID here
        return {
            'data': self.data
        }

    @classmethod
    def from_json(cls, json_data):
        UserData.create(
            # we enforce user to be the current user
            user=current_user,
            data=json_data['data']
        )

이렇게 할 수 있습니다.

class MyModel(peewee.Model):

  def __str__(self):
    r = {}
    for k in self._data.keys():
      try:
         r[k] = str(getattr(self, k))
      except:
         r[k] = json.dumps(getattr(self, k))
    return str(r)


class User(MyModel):
    email = CharField()
    status = CharField(default="enabled")
    firstname = CharField()
    lastname = CharField()
    class Meta:
        database = db

언급URL : https://stackoverflow.com/questions/21975920/peewee-model-to-json

반응형