【问题标题】:how to serialise a enum property in sqlalchemy using marshmallow如何使用棉花糖在 sqlalchemy 中序列化枚举属性
【发布时间】:2017-11-26 19:37:05
【问题描述】:

这是我的模型类

class Type(enum.Enum):
    Certified = "certified"
    Non_Certified = "non-certified"


class Status(enum.Enum):
    Approved = "Approved"
    Rejected = "Rejected"
    Published = "Published"
    Retired = "Retired"
    Waiting_for_Approval = "Waiting_for_Approval"


class DifficultyLevel(enum.Enum):
    Beginner = "Beginner"
    Intermediate = "Intermediate"
    Advanced = "Advanced"
    All = "All"


class ActiveStatus(enum.Enum):
    Archive = "archive"
    Restore = "restore"


class Course(Base):
    __tablename__ = 'course'
    id = Column(Integer, primary_key=True)
    course_code = Column(String(255))
    duration_in_hours = Column(Integer)
    default_eb_price = Column(Integer)
    modified_by = Column(Integer)
    modified_on = Column(DateTime)
    created_by = Column(Integer)
    created_at = Column(DateTime)
    type = Column(Enum(Type))
    certification_vendor = Column(String(255))
    certification_name = Column(String(255))
    micro_training_sessions = Column(Integer)
    status = Column(Enum(Status))
    title = Column(String(255))
    summary = Column(String(255))
    duration = Column(JSON)
    # Categories =
    delivery_language = Column(String(255))
    course_logo = Column(String(255))
    promo_video = Column(String(255))
    overview = Column(String(255))
    objectives = Column(String(255))
    suggested_attendees = Column(String(255))
    prerequisites = Column(String(255))
    difficulty_level = Column(Enum(DifficultyLevel))
    course_facts = Column(JSON)
    price = Column(String(255))
    list_price = Column(String(255))
    early_bird_price = Column(String(255))
    next_recommended_course = Column(postgresql.ARRAY(Integer))
    specialization_paths = Column(postgresql.ARRAY(Integer))
    active_status = Column(Enum(ActiveStatus))

    def __getitem__(self, item):
        return getattr(self, item)

    @property
    def serialize(self):
        """Return object data in easily serializeable format"""
        serialized_obj = {}
        for column in self.__table__.columns:
            serialized_obj[column.key] = self[column.key]
        return serialized_obj

这是用于编辑更改的控制器功能

def update_course_ctrl(obj,course_id):
    args = request.args
    course_schema = CourseSchema()
    if args is not None :
        if args['action'] == "archive":
            course = session.query(Course).filter_by(id=course_id).one()
            course.active_status = 'Archive'
            session.merge(course)
            session.commit()
            dump_data = course_schema.dump(course).data
            return dump_data
            # code to archive course
        if args['action'] == "restore":
            course = session.query(Course).filter_by(id=course_id).one()
            course.active_status = 'Restore'
            session.merge(course)
            session.commit()
            dump_data = course_schema.dump(course).data
            return dump_data
    course = Course(**obj.json)
    session.merge(course)
    session.commit()
    dump_data = course_schema.dump(course).data
    return dump_data

这是我在棉花糖文件中的代码

from marshmallow_sqlalchemy import ModelSchema
from sqlalchemy.orm import sessionmaker
from app.extensions import engine
from app.course.models import Course, Project, Topic, Resource


DBSession = sessionmaker(bind=engine)
session = DBSession()


class CourseSchema(ModelSchema):
    class Meta:
        model = Course
        sqla_session = session

调用此更新函数时出现此错误 TypeError: is not JSON serializable

【问题讨论】:

    标签: python-2.7 enums flask-sqlalchemy marshmallow


    【解决方案1】:

    您可以使用 Marshmallow 自定义方法字段

    from marshmallow import fields
    
    class CourseSchema(ModelSchema):
        type = fields.Method("get_course_type")
    
        def get_course_type(self, obj):
            return obj.type.value
    
        class Meta:
            model = Course
            sqla_session = session
    

    【讨论】:

      【解决方案2】:

      另一种选择是覆盖Enum__str__ 方法。例如

      class Type(enum.Enum):
          Certified = "certified"
          Non_Certified = "non-certified"
      
          def __str__(self):
              return self.value
      

      【讨论】:

        【解决方案3】:

        对于枚举字段,最简单的方法是通过 pip (pip install marshmallow_enum) 安装名为 marshmallow_enum 的包,将其导入您的项目,然后在您的棉花糖架构定义中使用您的自定义定义覆盖 SQLAlchemy 字段:

        from marshmallow_enum import EnumField
        ...
        
        
        class CourseSchema(ModelSchema):
            type = EnumField(Type, by_value=True)
        
            class Meta:
                model = Course
                sqla_session = session
        

        所有未被您的自定义定义覆盖的字段都将从您的模型中获取。

        您可以尝试使用 by_value 参数,它使您能够序列化枚举的名称(默认情况下)或值 (by_value=True)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-11-12
          • 2019-08-07
          • 2020-06-25
          • 1970-01-01
          • 2016-01-14
          • 2020-12-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多