What are the best practices for combining marshmallow schema definitions and OO in Python? [closed]










17















Assume a simple schema defined in marshmallow



class AddressSchema(Schema):
street=fields.String(required=True)
city=fields.String(required=True)
country=fields.String(default='USA')

class PersonSchema(Schema):
name=fields.String(required=True)
address=fields.Nested(AddressSchema())


The use case here is applications working with in-memory objects, and serialization/deserialization to JSON, i.e. no SQL database.



Using the standard json library I can parse JSON objects that conform to this schema, and access objects in a manner such as person1['address']['city'], but the use of typo-prone strings in verbose syntax is somewhat unsatisfactory.



Hand-crafted OO model



I could define a parallel OO model, and annotate my schema with @post_load decorators, for example:



class Address(object):
def __init__(self, street, city, country='USA'):
self.street=street
self.city=city
self.country=country

class Person(object):
def __init__(self, street, city=None):
self.street=street
self.city=city


But the repetition is not very nice (and I haven't even included descriptions in the schema).



No OO model



Arguably the explicit OO model doesn't buy much - it's basic data accessors, no behavior. I could get some syntactic sugar using jsobject, so that I could write for example person1.address.city. But this doesn't seem quite right either. As a developer I have no explicit python class API to consult to determine what fields to use, I can reference the marshmallow schema but this feels very indirect.



Code Generation



It would be fairly easy to generate the OO code above from the marshmallow schema definitions. I'm surprised there seems to be no such library. Perhaps code generation is considered very unpythonic? It would of course only be suitable only for data-access style class definitions; adding non-generic behavior would be strictly a no-no.



For users of the code, they would not need to know a codegen approach was used - everything would be there with an explicit API, with docs visible alongside the rest of the code in readthedocs etc.



Dynamic Classes



The other approach would be dynamic classes derived from the marshmallow definitions. Again, as far as I can tell there is no such library (although the range of dynamic class generation approaches in python is impressive, I may have missed some). Arguably this would not buy you that much over the jsobjects approach, but there may be some advantages - it would be possible to interweave this with some explicit code with defined behaviors. The downside of a dynamic approach is that explicit is favored over implicit in the Python world.



What's most pythonic?



The lack of libraries here means I'm either not finding something, or am not looking at this in a suitably pythonic way. I'm happy to contribute something to pypi but before adding yet-another meta-OO library I wanted to be sure I had done due diligence here.










share|improve this question













closed as primarily opinion-based by usr2564301, TylerH, Billal Begueradj, Mohammed Kashif, GhostCat Nov 16 '18 at 7:56


Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.













  • 1





    I asked a similar question in stackoverflow.com/questions/45831888/…

    – Teyras
    Aug 29 '17 at 11:36






  • 3





    "What's most pythonic" is at least on the edge of subjectivity :) I've upvoted the question as it's properly formulated and clear, but also voting to close.

    – BartoszKP
    Apr 17 '18 at 14:19







  • 1





    Take a look at Python 3.7 dataclasses

    – Jacques de Hooge
    Sep 3 '18 at 18:43











  • You can use pypi.org/project/marshmallow-dataclass and not have to define your schema manually.

    – lovasoa
    Feb 5 at 19:45















17















Assume a simple schema defined in marshmallow



class AddressSchema(Schema):
street=fields.String(required=True)
city=fields.String(required=True)
country=fields.String(default='USA')

class PersonSchema(Schema):
name=fields.String(required=True)
address=fields.Nested(AddressSchema())


The use case here is applications working with in-memory objects, and serialization/deserialization to JSON, i.e. no SQL database.



Using the standard json library I can parse JSON objects that conform to this schema, and access objects in a manner such as person1['address']['city'], but the use of typo-prone strings in verbose syntax is somewhat unsatisfactory.



Hand-crafted OO model



I could define a parallel OO model, and annotate my schema with @post_load decorators, for example:



class Address(object):
def __init__(self, street, city, country='USA'):
self.street=street
self.city=city
self.country=country

class Person(object):
def __init__(self, street, city=None):
self.street=street
self.city=city


But the repetition is not very nice (and I haven't even included descriptions in the schema).



No OO model



Arguably the explicit OO model doesn't buy much - it's basic data accessors, no behavior. I could get some syntactic sugar using jsobject, so that I could write for example person1.address.city. But this doesn't seem quite right either. As a developer I have no explicit python class API to consult to determine what fields to use, I can reference the marshmallow schema but this feels very indirect.



Code Generation



It would be fairly easy to generate the OO code above from the marshmallow schema definitions. I'm surprised there seems to be no such library. Perhaps code generation is considered very unpythonic? It would of course only be suitable only for data-access style class definitions; adding non-generic behavior would be strictly a no-no.



For users of the code, they would not need to know a codegen approach was used - everything would be there with an explicit API, with docs visible alongside the rest of the code in readthedocs etc.



Dynamic Classes



The other approach would be dynamic classes derived from the marshmallow definitions. Again, as far as I can tell there is no such library (although the range of dynamic class generation approaches in python is impressive, I may have missed some). Arguably this would not buy you that much over the jsobjects approach, but there may be some advantages - it would be possible to interweave this with some explicit code with defined behaviors. The downside of a dynamic approach is that explicit is favored over implicit in the Python world.



What's most pythonic?



The lack of libraries here means I'm either not finding something, or am not looking at this in a suitably pythonic way. I'm happy to contribute something to pypi but before adding yet-another meta-OO library I wanted to be sure I had done due diligence here.










share|improve this question













closed as primarily opinion-based by usr2564301, TylerH, Billal Begueradj, Mohammed Kashif, GhostCat Nov 16 '18 at 7:56


Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.













  • 1





    I asked a similar question in stackoverflow.com/questions/45831888/…

    – Teyras
    Aug 29 '17 at 11:36






  • 3





    "What's most pythonic" is at least on the edge of subjectivity :) I've upvoted the question as it's properly formulated and clear, but also voting to close.

    – BartoszKP
    Apr 17 '18 at 14:19







  • 1





    Take a look at Python 3.7 dataclasses

    – Jacques de Hooge
    Sep 3 '18 at 18:43











  • You can use pypi.org/project/marshmallow-dataclass and not have to define your schema manually.

    – lovasoa
    Feb 5 at 19:45













17












17








17


3






Assume a simple schema defined in marshmallow



class AddressSchema(Schema):
street=fields.String(required=True)
city=fields.String(required=True)
country=fields.String(default='USA')

class PersonSchema(Schema):
name=fields.String(required=True)
address=fields.Nested(AddressSchema())


The use case here is applications working with in-memory objects, and serialization/deserialization to JSON, i.e. no SQL database.



Using the standard json library I can parse JSON objects that conform to this schema, and access objects in a manner such as person1['address']['city'], but the use of typo-prone strings in verbose syntax is somewhat unsatisfactory.



Hand-crafted OO model



I could define a parallel OO model, and annotate my schema with @post_load decorators, for example:



class Address(object):
def __init__(self, street, city, country='USA'):
self.street=street
self.city=city
self.country=country

class Person(object):
def __init__(self, street, city=None):
self.street=street
self.city=city


But the repetition is not very nice (and I haven't even included descriptions in the schema).



No OO model



Arguably the explicit OO model doesn't buy much - it's basic data accessors, no behavior. I could get some syntactic sugar using jsobject, so that I could write for example person1.address.city. But this doesn't seem quite right either. As a developer I have no explicit python class API to consult to determine what fields to use, I can reference the marshmallow schema but this feels very indirect.



Code Generation



It would be fairly easy to generate the OO code above from the marshmallow schema definitions. I'm surprised there seems to be no such library. Perhaps code generation is considered very unpythonic? It would of course only be suitable only for data-access style class definitions; adding non-generic behavior would be strictly a no-no.



For users of the code, they would not need to know a codegen approach was used - everything would be there with an explicit API, with docs visible alongside the rest of the code in readthedocs etc.



Dynamic Classes



The other approach would be dynamic classes derived from the marshmallow definitions. Again, as far as I can tell there is no such library (although the range of dynamic class generation approaches in python is impressive, I may have missed some). Arguably this would not buy you that much over the jsobjects approach, but there may be some advantages - it would be possible to interweave this with some explicit code with defined behaviors. The downside of a dynamic approach is that explicit is favored over implicit in the Python world.



What's most pythonic?



The lack of libraries here means I'm either not finding something, or am not looking at this in a suitably pythonic way. I'm happy to contribute something to pypi but before adding yet-another meta-OO library I wanted to be sure I had done due diligence here.










share|improve this question














Assume a simple schema defined in marshmallow



class AddressSchema(Schema):
street=fields.String(required=True)
city=fields.String(required=True)
country=fields.String(default='USA')

class PersonSchema(Schema):
name=fields.String(required=True)
address=fields.Nested(AddressSchema())


The use case here is applications working with in-memory objects, and serialization/deserialization to JSON, i.e. no SQL database.



Using the standard json library I can parse JSON objects that conform to this schema, and access objects in a manner such as person1['address']['city'], but the use of typo-prone strings in verbose syntax is somewhat unsatisfactory.



Hand-crafted OO model



I could define a parallel OO model, and annotate my schema with @post_load decorators, for example:



class Address(object):
def __init__(self, street, city, country='USA'):
self.street=street
self.city=city
self.country=country

class Person(object):
def __init__(self, street, city=None):
self.street=street
self.city=city


But the repetition is not very nice (and I haven't even included descriptions in the schema).



No OO model



Arguably the explicit OO model doesn't buy much - it's basic data accessors, no behavior. I could get some syntactic sugar using jsobject, so that I could write for example person1.address.city. But this doesn't seem quite right either. As a developer I have no explicit python class API to consult to determine what fields to use, I can reference the marshmallow schema but this feels very indirect.



Code Generation



It would be fairly easy to generate the OO code above from the marshmallow schema definitions. I'm surprised there seems to be no such library. Perhaps code generation is considered very unpythonic? It would of course only be suitable only for data-access style class definitions; adding non-generic behavior would be strictly a no-no.



For users of the code, they would not need to know a codegen approach was used - everything would be there with an explicit API, with docs visible alongside the rest of the code in readthedocs etc.



Dynamic Classes



The other approach would be dynamic classes derived from the marshmallow definitions. Again, as far as I can tell there is no such library (although the range of dynamic class generation approaches in python is impressive, I may have missed some). Arguably this would not buy you that much over the jsobjects approach, but there may be some advantages - it would be possible to interweave this with some explicit code with defined behaviors. The downside of a dynamic approach is that explicit is favored over implicit in the Python world.



What's most pythonic?



The lack of libraries here means I'm either not finding something, or am not looking at this in a suitably pythonic way. I'm happy to contribute something to pypi but before adding yet-another meta-OO library I wanted to be sure I had done due diligence here.







python oop marshmallow






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Aug 21 '17 at 21:27









cmungallcmungall

32714




32714




closed as primarily opinion-based by usr2564301, TylerH, Billal Begueradj, Mohammed Kashif, GhostCat Nov 16 '18 at 7:56


Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.









closed as primarily opinion-based by usr2564301, TylerH, Billal Begueradj, Mohammed Kashif, GhostCat Nov 16 '18 at 7:56


Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.









  • 1





    I asked a similar question in stackoverflow.com/questions/45831888/…

    – Teyras
    Aug 29 '17 at 11:36






  • 3





    "What's most pythonic" is at least on the edge of subjectivity :) I've upvoted the question as it's properly formulated and clear, but also voting to close.

    – BartoszKP
    Apr 17 '18 at 14:19







  • 1





    Take a look at Python 3.7 dataclasses

    – Jacques de Hooge
    Sep 3 '18 at 18:43











  • You can use pypi.org/project/marshmallow-dataclass and not have to define your schema manually.

    – lovasoa
    Feb 5 at 19:45












  • 1





    I asked a similar question in stackoverflow.com/questions/45831888/…

    – Teyras
    Aug 29 '17 at 11:36






  • 3





    "What's most pythonic" is at least on the edge of subjectivity :) I've upvoted the question as it's properly formulated and clear, but also voting to close.

    – BartoszKP
    Apr 17 '18 at 14:19







  • 1





    Take a look at Python 3.7 dataclasses

    – Jacques de Hooge
    Sep 3 '18 at 18:43











  • You can use pypi.org/project/marshmallow-dataclass and not have to define your schema manually.

    – lovasoa
    Feb 5 at 19:45







1




1





I asked a similar question in stackoverflow.com/questions/45831888/…

– Teyras
Aug 29 '17 at 11:36





I asked a similar question in stackoverflow.com/questions/45831888/…

– Teyras
Aug 29 '17 at 11:36




3




3





"What's most pythonic" is at least on the edge of subjectivity :) I've upvoted the question as it's properly formulated and clear, but also voting to close.

– BartoszKP
Apr 17 '18 at 14:19






"What's most pythonic" is at least on the edge of subjectivity :) I've upvoted the question as it's properly formulated and clear, but also voting to close.

– BartoszKP
Apr 17 '18 at 14:19





1




1





Take a look at Python 3.7 dataclasses

– Jacques de Hooge
Sep 3 '18 at 18:43





Take a look at Python 3.7 dataclasses

– Jacques de Hooge
Sep 3 '18 at 18:43













You can use pypi.org/project/marshmallow-dataclass and not have to define your schema manually.

– lovasoa
Feb 5 at 19:45





You can use pypi.org/project/marshmallow-dataclass and not have to define your schema manually.

– lovasoa
Feb 5 at 19:45












1 Answer
1






active

oldest

votes


















0














Your question is quite vague, and so will be my answer, and quite subjective I hope that's ok. I am just some dude who spent the day reading serialization options in python.



I think that Marshmallow is fundamentally unpythonic, and there isn't a great way to use it, I don't intend to use it. I'll give what for me is two definitive examples.



  1. You have a class that has as a field a mixed-type list of other objects. This is python so you're allowed to do that. In marshmallow you can't deal with this natively or neatly. There's a very natural solution, which is to put down/up a list of the classes by using their registered serializers. But in Marshmallow you'd have to write your own code and change the serializer of every possible class it could to ensure it's registered in something you pass to a nested func. It doesn't register serializers for classes, you'd have to add that. Issue describing.

  2. You want to serialize a mixed (literal) dict of strings to unknown classes. This is pretty much the same as above, you'd have to implement it yourself. Plus you'd have to write a serializer/de yourself for every primitive you wanted to do this for. They wrote code for primitives as fields but not schemas, which to me is not batteries included or one obvious way.

General serializing libraries are kind of a deep rabbit hole because what you're really talking about requires elements of a type system, a parser and a graph traversal algorithm all in one go. Marshmallow doesn't do recursive parsing by default, so it fails point (2). On point (1), (kind of because of 2), it either requires extensive hacking or requires you to accept a java-like type system (everything is of known, enumerated type).



You asked about general serializing libraries, I found the library camel interesting and the blog post around it. For pickle, there's a powerful extension called dill and a mixin that handles versioning






share|improve this answer





























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    Your question is quite vague, and so will be my answer, and quite subjective I hope that's ok. I am just some dude who spent the day reading serialization options in python.



    I think that Marshmallow is fundamentally unpythonic, and there isn't a great way to use it, I don't intend to use it. I'll give what for me is two definitive examples.



    1. You have a class that has as a field a mixed-type list of other objects. This is python so you're allowed to do that. In marshmallow you can't deal with this natively or neatly. There's a very natural solution, which is to put down/up a list of the classes by using their registered serializers. But in Marshmallow you'd have to write your own code and change the serializer of every possible class it could to ensure it's registered in something you pass to a nested func. It doesn't register serializers for classes, you'd have to add that. Issue describing.

    2. You want to serialize a mixed (literal) dict of strings to unknown classes. This is pretty much the same as above, you'd have to implement it yourself. Plus you'd have to write a serializer/de yourself for every primitive you wanted to do this for. They wrote code for primitives as fields but not schemas, which to me is not batteries included or one obvious way.

    General serializing libraries are kind of a deep rabbit hole because what you're really talking about requires elements of a type system, a parser and a graph traversal algorithm all in one go. Marshmallow doesn't do recursive parsing by default, so it fails point (2). On point (1), (kind of because of 2), it either requires extensive hacking or requires you to accept a java-like type system (everything is of known, enumerated type).



    You asked about general serializing libraries, I found the library camel interesting and the blog post around it. For pickle, there's a powerful extension called dill and a mixin that handles versioning






    share|improve this answer



























      0














      Your question is quite vague, and so will be my answer, and quite subjective I hope that's ok. I am just some dude who spent the day reading serialization options in python.



      I think that Marshmallow is fundamentally unpythonic, and there isn't a great way to use it, I don't intend to use it. I'll give what for me is two definitive examples.



      1. You have a class that has as a field a mixed-type list of other objects. This is python so you're allowed to do that. In marshmallow you can't deal with this natively or neatly. There's a very natural solution, which is to put down/up a list of the classes by using their registered serializers. But in Marshmallow you'd have to write your own code and change the serializer of every possible class it could to ensure it's registered in something you pass to a nested func. It doesn't register serializers for classes, you'd have to add that. Issue describing.

      2. You want to serialize a mixed (literal) dict of strings to unknown classes. This is pretty much the same as above, you'd have to implement it yourself. Plus you'd have to write a serializer/de yourself for every primitive you wanted to do this for. They wrote code for primitives as fields but not schemas, which to me is not batteries included or one obvious way.

      General serializing libraries are kind of a deep rabbit hole because what you're really talking about requires elements of a type system, a parser and a graph traversal algorithm all in one go. Marshmallow doesn't do recursive parsing by default, so it fails point (2). On point (1), (kind of because of 2), it either requires extensive hacking or requires you to accept a java-like type system (everything is of known, enumerated type).



      You asked about general serializing libraries, I found the library camel interesting and the blog post around it. For pickle, there's a powerful extension called dill and a mixin that handles versioning






      share|improve this answer

























        0












        0








        0







        Your question is quite vague, and so will be my answer, and quite subjective I hope that's ok. I am just some dude who spent the day reading serialization options in python.



        I think that Marshmallow is fundamentally unpythonic, and there isn't a great way to use it, I don't intend to use it. I'll give what for me is two definitive examples.



        1. You have a class that has as a field a mixed-type list of other objects. This is python so you're allowed to do that. In marshmallow you can't deal with this natively or neatly. There's a very natural solution, which is to put down/up a list of the classes by using their registered serializers. But in Marshmallow you'd have to write your own code and change the serializer of every possible class it could to ensure it's registered in something you pass to a nested func. It doesn't register serializers for classes, you'd have to add that. Issue describing.

        2. You want to serialize a mixed (literal) dict of strings to unknown classes. This is pretty much the same as above, you'd have to implement it yourself. Plus you'd have to write a serializer/de yourself for every primitive you wanted to do this for. They wrote code for primitives as fields but not schemas, which to me is not batteries included or one obvious way.

        General serializing libraries are kind of a deep rabbit hole because what you're really talking about requires elements of a type system, a parser and a graph traversal algorithm all in one go. Marshmallow doesn't do recursive parsing by default, so it fails point (2). On point (1), (kind of because of 2), it either requires extensive hacking or requires you to accept a java-like type system (everything is of known, enumerated type).



        You asked about general serializing libraries, I found the library camel interesting and the blog post around it. For pickle, there's a powerful extension called dill and a mixin that handles versioning






        share|improve this answer













        Your question is quite vague, and so will be my answer, and quite subjective I hope that's ok. I am just some dude who spent the day reading serialization options in python.



        I think that Marshmallow is fundamentally unpythonic, and there isn't a great way to use it, I don't intend to use it. I'll give what for me is two definitive examples.



        1. You have a class that has as a field a mixed-type list of other objects. This is python so you're allowed to do that. In marshmallow you can't deal with this natively or neatly. There's a very natural solution, which is to put down/up a list of the classes by using their registered serializers. But in Marshmallow you'd have to write your own code and change the serializer of every possible class it could to ensure it's registered in something you pass to a nested func. It doesn't register serializers for classes, you'd have to add that. Issue describing.

        2. You want to serialize a mixed (literal) dict of strings to unknown classes. This is pretty much the same as above, you'd have to implement it yourself. Plus you'd have to write a serializer/de yourself for every primitive you wanted to do this for. They wrote code for primitives as fields but not schemas, which to me is not batteries included or one obvious way.

        General serializing libraries are kind of a deep rabbit hole because what you're really talking about requires elements of a type system, a parser and a graph traversal algorithm all in one go. Marshmallow doesn't do recursive parsing by default, so it fails point (2). On point (1), (kind of because of 2), it either requires extensive hacking or requires you to accept a java-like type system (everything is of known, enumerated type).



        You asked about general serializing libraries, I found the library camel interesting and the blog post around it. For pickle, there's a powerful extension called dill and a mixin that handles versioning







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 15 '18 at 21:21









        zimabluezimablue

        135




        135















            Popular posts from this blog

            Top Tejano songwriter Luis Silva dead of heart attack at 64

            ReactJS Fetched API data displays live - need Data displayed static

            政党