嵌套结构时,棉花糖反序列化失败

mel*_*r55 0 python sqlalchemy flask marshmallow

我正在尝试用棉花糖反序列化深层结构。例如:

hour = {
    'day': {
        'name': 'monday'
    }
}
loaded_hour, error = HoursSerializationSchema().load(hour) # this works

new_practitioner_at_location = {
    'hours': [
        hour
    ]
}
loaded, error = PractitionerToServiceLocationSerializationSchema().load(new_practitioner_at_location) # this fails
Run Code Online (Sandbox Code Playgroud)

当我尝试反序列化时,new_practitioner_at_location我得到以下信息(发生在序列化程序使用“ day”键时):

AttributeError: 'dict' object has no attribute '_sa_instance_state'

请注意,当相同的数据结构(小时)未嵌套在时,相同的模式可以反序列化该数据结构new_practitioner_at_location

显示问题的自包含脚本:

from sqlalchemy import Column, Integer, ForeignKey, String
from sqlalchemy.orm import relationship, backref
from sqlalchemy.ext.declarative import declarative_base
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from flask_migrate import Migrate

base = declarative_base()


class HoursDay(base):
    __tablename__ = 'HoursDay'
    uid = Column(Integer, primary_key=True)

    name = Column(String)

    hour_id = Column(Integer, ForeignKey('Hours.uid'))
    hour = relationship("Hours", back_populates="day")

    def __init__(self, **kwargs):
        super().__init__(**kwargs)


class Hours(base):
    __tablename__ = 'Hours'
    uid = Column(Integer, primary_key=True)

    practitioner_at_location_id = Column(Integer, ForeignKey('PractitionerToServiceLocation.uid'))
    practitioner_at_location = relationship('PractitionerToServiceLocation', back_populates="hours")

    day = relationship(HoursDay, uselist=False, back_populates="hour")

    def __repr__(self):
        return f'<Hours {self.uid}>'


class PractitionerToServiceLocation(base):
    """
    A practitioner practices at a number of service locations.
    """
    __tablename__ = 'PractitionerToServiceLocation'
    uid = Column(Integer, primary_key=True)

    hours = relationship("Hours", back_populates="practitioner_at_location")

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def __repr__(self):
        return f'<PractitionerToServiceLocation {self.uid}>'


app = Flask(__name__)
app.config.from_object(os.environ['APP_SETTINGS'])
db = SQLAlchemy(app, model_class=base)
ma = Marshmallow(app)
migrate = Migrate(app, db)

from marshmallow import fields


class HoursDaySerializationSchema(ma.ModelSchema):
    class Meta:
        model = HoursDay


class HoursSerializationSchema(ma.ModelSchema):
    class Meta:
        model = Hours

    day = fields.Nested(HoursDaySerializationSchema)


class PractitionerToServiceLocationSerializationSchema(ma.ModelSchema):
    class Meta:
        model = PractitionerToServiceLocation

        hours = fields.Nested('HoursSerializationSchema', many=True)


if __name__ == "__main__":
    hour = {
        'day': {
            'name': 'monday'
        }
    }
    loaded_hour, error = HoursSerializationSchema().load(hour) # this works

    new_practitioner_at_location = {
        'hours': [
            hour
        ]
    }
    loaded, error = PractitionerToServiceLocationSerializationSchema().load(new_practitioner_at_location) # this fails
    print('hi')
Run Code Online (Sandbox Code Playgroud)

更新:

我认为正在发生的事情是,HoursDay在尝试对new_practitioner_at_locationdict 进行反序列化时,棉花糖并未尝试对对象进行反序列化。如果我backpopulatesHoursDay.hour字段中删除该行为,那么您可以看到它只是将未序列化的数据结构分配给该字段。这对我来说根本没有任何意义,尤其是当您hour直接对dict进行反序列化而不是将其嵌入内部时,它就可以工作了new_practitioner_at_location。任何帮助,将不胜感激。

Thi*_*ter 5

这是一个像错字一样简单的错误:

class PractitionerToServiceLocationSerializationSchema(ma.ModelSchema):
    class Meta:
        model = PractitionerToServiceLocation

        hours = fields.Nested('HoursSerializationSchema', many=True)
Run Code Online (Sandbox Code Playgroud)

您正在定义hoursinside class Meta,但是它必须在您的模式本身中:

class PractitionerToServiceLocationSerializationSchema(ma.ModelSchema):
    class Meta:
        model = PractitionerToServiceLocation

    hours = fields.Nested('HoursSerializationSchema', many=True)
Run Code Online (Sandbox Code Playgroud)

  • 哇。您正在目睹我有史以来遇到过的最困难的脸部按摩之一。 (2认同)