You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Presently, attempting to use ModelSchema to model a SQLAlchemy model that contains a relationship that employs a one-to-one relationship, that is, they take advantage of the backref()'s uselist=False argument, results in an TypeError when attempting to serialize the relationship.
e.g. given something like… (note, this is pseudocode-y)
class Child(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255))
class Parent(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255))
child_id = db.Column(db.Integer, db.ForeignKey('child.id'))
only_child = db.relationship('Child', backref=db.backref('father', uselist=False))
class ChildSchema(ma.ModelSchema):
class Meta:
model = Child
class ParentSchema(ma.ModelSchema):
class Meta:
model = Parent
…performing a dump on a record is where the "fun starts"…
child = child.get_or_404(1)
child_schema = ChildSchema()
child_schema.dump(child).data
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-6-2a42b0948473> in <module>()
1 # hagbard = registrants.get_or_404(2)
----> 2 registrant_schema.dump(hagbard).data
/env/lib/python2.7/site-packages/marshmallow/schema.pyc in dump(self, obj, many, update_fields, **kwargs)
562 dict_class=self.dict_class,
563 index_errors=self.opts.index_errors,
--> 564 **kwargs
565 )
566 result = self._postprocess(preresult, many, obj=obj)
/env/lib/python2.7/site-packages/marshmallow/marshalling.pyc in serialize(self, obj, fields_dict, many, strict, skip_missing, accessor, dict_class, index_errors, index)
135 field_name=key,
136 field_obj=field_obj,
--> 137 index=(index if index_errors else None)
138 )
139 skip_conds = (
/env/lib/python2.7/site-packages/marshmallow/marshalling.pyc in call_and_store(self, getter_func, data, field_name, field_obj, index)
54 """
55 try:
---> 56 value = getter_func(data)
57 except ValidationError as err: # Store validation errors
58 self.error_fields.append(field_obj)
/env/lib/python2.7/site-packages/marshmallow/marshalling.pyc in <lambda>(d)
129 for attr_name, field_obj in iteritems(fields_dict):
130 key = ''.join([self.prefix, attr_name])
--> 131 getter = lambda d: field_obj.serialize(attr_name, d, accessor=accessor)
132 value = self.call_and_store(
133 getter_func=getter,
/env/lib/python2.7/site-packages/marshmallow/fields.py in serialize(self, attr, obj, accessor)
219 else:
220 return self.default
--> 221 return self._serialize(value, attr, obj)
222
223 def deserialize(self, value):
/env/lib/python2.7/site-packages/marshmallow/fields.py in _serialize(self, value, attr, obj)
1215 # else:
1216 # items = []
-> 1217 items = [self.keygetter(v) for v in value]
1218
1219 if not items:
TypeError: 'NoneType' object is not iterable
However, changing the Parent model's relationship to be only_child = db.relationship('Child', backref='father') fixes the issue.
I suspect this is because with the uselist=False, "relationship-oriented" attributes are no longer lists (even empty ones) but are rather simply None values. I tried putting in some guards to prevent the issue if value were None (there on line 1217 where it's blowing up) but simply referencing the value variable seemed to raise the error, e.g. even a if value is not None: caused the same TypeError.
I'd be really nice if this were supported, as this is the canonical way to represent 1:1 relationships AFAIK. Many kudos to you for an already great library, and thanks for your hard work!
(Also, while I realize this issue is coming up in marshmallow "proper", and might not be your purview, it seems to be a SQLAlchemy related issue and figured it would belong best here than under the vanilla marshmallow project's issues. If this is in error, I'm happy to open this issue there or elsewhere!)
Presently, attempting to use
ModelSchema
to model a SQLAlchemy model that contains a relationship that employs a one-to-one relationship, that is, they take advantage of thebackref()
'suselist=False
argument, results in anTypeError
when attempting to serialize the relationship.e.g. given something like… (note, this is pseudocode-y)
…performing a dump on a record is where the "fun starts"…
However, changing the Parent model's relationship to be
only_child = db.relationship('Child', backref='father')
fixes the issue.I suspect this is because with the
uselist=False
, "relationship-oriented" attributes are no longer lists (even empty ones) but are rather simplyNone
values. I tried putting in some guards to prevent the issue if value were None (there on line 1217 where it's blowing up) but simply referencing thevalue
variable seemed to raise the error, e.g. even aif value is not None:
caused the sameTypeError
.I'd be really nice if this were supported, as this is the canonical way to represent 1:1 relationships AFAIK. Many kudos to you for an already great library, and thanks for your hard work!
(Also, while I realize this issue is coming up in marshmallow "proper", and might not be your purview, it seems to be a SQLAlchemy related issue and figured it would belong best here than under the vanilla marshmallow project's issues. If this is in error, I'm happy to open this issue there or elsewhere!)
q.v.: http://docs.sqlalchemy.org/en/rel_1_0/orm/basic_relationships.html#one-to-one
The text was updated successfully, but these errors were encountered: