I'm using flask-marshmallow (marshmallow=v3.0.0rc1, flask-marshmallow=0.9.0) and flask-sqlalchemy (sqlalchemy=1.2.16, flask-sqlalchemy=2.3.2)
I have this model and schema.
from marshmallow import post_load, fields
from .datastore import sqla_database as db
from .extensions import marshmallow as ma
class Study(db.Model):
_id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False)
tests = db.relationship("Test", backref="study", lazy='select', cascade="all, delete-orphan")
@property
def test_count(self):
return len(self.tests)
class StudySchema(ma.ModelSchema):
test_count = fields.Integer(dump_only=True)
class Meta:
model = Study
sqla_session = db.session
schema = StudySchema()
payload = request.get_json()
schema.load(data=payload, instance=Study.query.get(payload["_id"]))
schema.session.commit()
If I perform a PUT operation with this payload
{'_id': 1, 'name': 'Study1', 'test_count': 0}
I get the following exception marshmallow.exceptions.ValidationError: {'test_count': ['Unknown field.']}
If I remove the dump_only=True
I get this exception AttributeError: can't set attribute
which makes sense to me because it's trying to set test_count with no setter method on model class.
What I do not understand is why is the attribute is not ignored with dump_only
. Why is marshmallow still trying to validate and understand this field during load when it's marked as dump_only
?
In marshmallow 2, unknown or dump_only fields are ignored from input. Unless the user decides to add his own validation to error on them.
In marshmallow 3, we changed that to offer three possibilities (see docs):
- RAISE (default)
- EXCLUDE (like marshmallow 2)
- INCLUDE (pass data without validation)
There's been discussions about how to deal with dump_only fields and we came to the conclusion that from client perspective, those should be treated just as unknown fields (see https://github.com/marshmallow-code/marshmallow/issues/875).
Bottom line, your PUT payload should not include dump_only fields. Or you could set the EXCLUDE policy to your schema, but I'd favor the former option.
来源:https://stackoverflow.com/questions/54391524/sqlalchemy-property-causes-unknown-field-error-in-marshmallow-with-dump-only