【问题标题】:Serialize SQLAlchemy Objects that have children with multiple children序列化具有多个孩子的孩子的 SQLAlchemy 对象
【发布时间】:2014-09-17 17:53:42
【问题描述】:

我有一个使用marshmallow 序列化的 SLQALchemy 对象。

对象有 N 个喜欢和 N 个 cmets。它看起来像这样:

class Parent():

    __tablename__ = 'parent'

    title = Column(db.String(100), unique=True, nullable=False)
    description = Column(db.String(500))
    created_at = Column(db.DateTime, nullable=False, default=dt.datetime.utcnow)
    comments = relationship('Comment')
    likes = relationship('Like')

序列化器如下所示:

class CommentSerializer(Serializer):
    class Meta:
        fields = ('id', 'text', 'created_at', 'parent_id')

class LikeSerializer(Serializer):
    class Meta:
        fields = ('id', 'created_at', 'parent_id')

class ParentSerializer(Serializer):
    comments = fields.Nested(CommentSerializer)
    likes = fields.Nested(LikeSerializer)

    class Meta:
        fields = ('id', 'title', 'description', 'comments', 'likes')

我尝试像这样在视图中运行它:

allParents = Parent.query.all()

然后用这个把它变成 JSON:

return jsonify({"parents": ParentSerializer(allParents, many=True).data})

当我尝试运行它时,我收到错误 list indices must be integers, not str。它来自marshmallow/serializer.py。当我在那里记录一些东西时,看起来棉花糖正试图访问<Comment> 列表的text 属性。它应该分别访问每个<Comment>,然后访问text 属性。

我的序列化程序中是否缺少某些内容?我知道在 ParentSerializer 中发送 many=True 参数会告诉 marshmallow 它应该遍历 <Parent> 的列表。有没有办法告诉棉花糖它也应该期待很多<Comment><Like>

【问题讨论】:

    标签: python flask sqlalchemy flask-sqlalchemy marshmallow


    【解决方案1】:

    有没有办法告诉棉花糖它也应该期待许多<Comment><Like>

    是的。您也可以将many=True 传递给Nested 字段。

    class ParentSerializer(Serializer):
        comments = fields.Nested(CommentSerializer, many=True)
        likes = fields.Nested(LikeSerializer, many=True)
    

    【讨论】:

      【解决方案2】:

      有没有办法告诉棉花糖它也应该期待许多<Comment><Like>

      或者,您可以这样做:

      class ParentSerializer(Serializer):
          comments = fields.List(fields.Nested(CommentSerializer))
          likes = fields.List(fields.Nested(LikeSerializer))
      

      【讨论】:

        【解决方案3】:

        查看https://docs.sqlalchemy.org/en/13/orm/basic_relationships.html#association-object
        你可以使用你的自定义序列化函数。

         class Company(db.Model):
          __tablename__ = 'company'
        
          id = db.Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
          name = db.Column(db.String(255), nullable=False)
          users = relationship("CompanyUser", back_populates="company")
        
          def serialize(self):
           main =  { c.key: getattr(self, c.key) for c in inspect(self).mapper.column_attrs }
           children = [user.serialize() for user in self.users] 
           main['users'] = children
           return  main
        

        而且,您可以在其他模型类中使用这种“通用”可序列化:

         def serialize(self):
            return { c.key: getattr(self, c.key) for c in inspect(self).mapper.column_attrs }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-08-07
          • 2020-12-16
          • 1970-01-01
          • 2019-04-18
          • 1970-01-01
          • 1970-01-01
          • 2019-02-17
          • 1970-01-01
          相关资源
          最近更新 更多