-
-
Notifications
You must be signed in to change notification settings - Fork 646
Open
Description
Link: marshmallow.readthedocs.io/en/stable/nesting.html#nesting-a-schema-within-itself
class UserSchema(Schema):
name = fields.String()
email = fields.Email()
# Use the 'exclude' argument to avoid infinite recursion
employer = fields.Nested(lambda: UserSchema(exclude=("employer",)))
friends = fields.List(fields.Nested(lambda: UserSchema()))
user = User("Steve", "[email protected]")
user.friends.append(User("Mike", "[email protected]"))
user.friends.append(User("Joe", "[email protected]"))
user.employer = User("Dirk", "[email protected]")
result = UserSchema().dump(user)
pprint(result, indent=2)
# {
# "name": "Steve",
# "email": "[email protected]",
# "friends": [
# {
# "name": "Mike",
# "email": "[email protected]",
# "friends": [],
# "employer": null
# },
# {
# "name": "Joe",
# "email": "[email protected]",
# "friends": [],
# "employer": null
# }
# ],
# "employer": {
# "name": "Dirk",
# "email": "[email protected]",
# "friends": []
# }
# }While the example usage itself doesn't run into infinite recursion, the schema is prone to it:
user = User("Steve", "[email protected]")
dirk = User("Dirk", "[email protected]")
user.employer = dirk
dirk.friends.append(user)
result = UserSchema().dump(user)
pprint(result, indent=2)user = User("Steve", "[email protected]")
mike = User("Mike", "[email protected]")
joe = User("Joe", "[email protected]")
user.friends.append(mike)
mike.friends.append(user)
user.friends.append(joe)
joe.friends.append(user)
dirk = User("Dirk", "[email protected]")
user.employer = dirk
dirk.friends.append(user)
result = UserSchema().dump(user)
pprint(result, indent=2)Possible solutions:
- Make either relationship a leaf node
class UserSchema(Schema):
name = fields.String()
email = fields.Email()
# Use the 'exclude' argument to avoid infinite recursion
employer = fields.Nested(lambda: UserSchema(exclude=("employer", "friends")))
friends = fields.List(fields.Nested(lambda: UserSchema(exclude=("friends",))))
class UserSchema(Schema):
name = fields.String()
email = fields.Email()
# Use the 'exclude' argument to avoid infinite recursion
employer = fields.Nested(lambda: UserSchema(exclude=("employer",)))
friends = fields.List(fields.Nested(lambda: UserSchema(exclude=("employer", "friends"))))- Make both relationships leaf nodes
class UserSchema(Schema):
name = fields.String()
email = fields.Email()
# Use the 'exclude' argument to avoid infinite recursion
employer = fields.Nested(lambda: UserSchema(exclude=("employer", "friends")))
friends = fields.List(fields.Nested(lambda: UserSchema(exclude=("employer", "friends"))))- Use a single relationship
class UserSchema(Schema):
name = fields.String()
email = fields.Email()
# Use the 'exclude' argument to avoid infinite recursion
friends = fields.List(fields.Nested(lambda: UserSchema(exclude=("friends",))))Happy to contribute if accepted!
Metadata
Metadata
Assignees
Labels
No labels