Ошибка сериализации Flask API — даты … является ли зефир ответом?

#python #api #flask #serialization #flask-restful

Вопрос:

Я пытаюсь научить себя, как создать API-интерфейс flask. Я начал с этого шаблона схемы того, как структурировать проект. https://github.com/Zukkster/flask-restful

Когда я начинаю работать с датами и базой данных PostgreSQL, я сталкиваюсь с ошибками сериализации

API работает, и он записывает данные в базу данных, и я думаю, что в конце концов понял, что ошибка, которую я получаю, заключается в том, что Postman возвращает json записанной записи. Поэтому я думаю, что проблема в «def json(self)» кода «модели». До тех пор, пока я не добавил DecoderDateTime, я получал ошибку сериализации, мне не удавалось правильно ее декодировать, и теперь ошибка немного более загадочна

 >   File "C:Python38Libjsondecoder.py", line 340, in decode
>     raise JSONDecodeError("Extra data", s, end) json.decoder.JSONDecodeError: Extra data: line 1 column 5 (char 4)
 

Это то, с чем должна справиться Зефирка? и мне просто нужно использовать это и определить схему. Вся эта сериализация дат выглядит отвратительно (даты всегда такие) будет ли Зефир просто справляться с этой сложностью? Я думаю, это просто потому, что мне нужно посмотреть более новый учебник? Что мне понравилось в этом учебнике, так это то, что он фокусируется на том, как должен быть структурирован проект, а не просто на создании одного файла кода … на что большинство разработчиков посмотрят и высмеют вас за городом.

resourcesforce_element_group.py

 from flask_restful import Resource, reqparse
#from flask_jwt import jwt_required
from models.force_element_group import ForceElementGroupModel


import json
import datetime
from json import JSONEncoder


class DateTimeEncoder(JSONEncoder):
    # Override the default method
    def default(self, obj):
        if isinstance(obj, (datetime.date, datetime.datetime)):
            return obj.isoformat()


class ForceElementGroup(Resource):
    parser = reqparse.RequestParser()  # only allow price changes, no name changes allowed
    parser.add_argument('created_user', type=str, required=True, help='The name of the user creating the group - if left blank created as admin')
    # parser.add_argument('created_timestamp', type = lambda d: datetime.strptime(d, '%Y%m%d'))
    parser.add_argument('created_timestamp', type=str, required=True, help='Need date')

    # @jwt_required()
    def post(self, force_element_group_name):
        if ForceElementGroupModel.find_by_name(force_element_group_name):
            return {'message': "An Force Element with name '{}' already exists.".format(force_element_group_name)}, 400

        data = ForceElementGroup.parser.parse_args()
        force_element_group = ForceElementGroupModel(force_element_group_name, data['created_user'], json.dumps(data['created_timestamp'], cls=DateTimeEncoder))

        try:
            force_element_group.save_to_db()
        except:
            return {"message": "An error occurred inserting the item."}, 500
        return force_element_group.json(), 201


class ForceElementGroupList(Resource):
    # @jwt_required()
    def get(self):
        return {'force_element_groups': [force_element_group.json() for force_element_group in
                                         ForceElementGroupModel.query.all()]}
 

modelforce_element_group.py

 from db import db
from datetime import datetime
import json
import dateutil.parser

# custom Decoder
def DecodeDateTime(empDict):
   if 'joindate' in empDict:
      empDict["joindate"] = dateutil.parser.parse(empDict["joindate"])
      return empDict

class ForceElementGroupModel(db.Model):
    __tablename__ = 'force_element_group'
    __table_args__ = {'schema': 'force_element'}

    force_element_group_id = db.Column(db.Integer, primary_key=True)
    force_element_group_name = db.Column(db.String(100), nullable=False)
    created_user = db.Column(db.String(100), nullable=False, default='Admin')
    created_timestamp = db.Column(db.DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow)# server_default=sqlalchemy.sql.func.now())#default=datetime.utcnow

    def __init__(self, force_element_group_name, created_user, created_timestamp):
        self.force_element_group_name = force_element_group_name
        self.created_user = created_user
        self.created_timestamp = created_timestamp

    def json(self):
        return {'force_element_group_name': self.force_element_group_name, 'created_user': self.created_user, 'created_timestamp':  json.loads(str(self.created_timestamp), object_hook=DecodeDateTime)}

    @classmethod
    def find_by_name(cls, force_element_group_name):
        return cls.query.filter_by(force_element_group_name=force_element_group_name).first()  # simple TOP 1 select

    def save_to_db(self):  # Upserting data
        db.session.add(self)
        db.session.commit()  # Balla

    def delete_from_db(self):
        db.session.delete(self)
        db.session.commit()