Hey Iain, I basically use two patterns when it comes to handling the impedance mismatch between my persistence layer (DB with SQLAlchemy), domain models, and view models (JSON objects for Angular.js):
1.) This first pattern I use consists of maintaining two separate models for the domain and persistence layer. I personally prefer to use SQLAlchemy's declarative approach, but many times my domain models do not associate directly with all the fields in the persistence models. In these situations I rely heavily on the Repository Pattern ( https://msdn.microsoft.com/en-us/library/ff649690.aspx) for dealing with the conversion of domain objects to the persistence objects. Unfortunately, this results in a quite a bit of redundant code since the domain models will contain most of the same fields and structures as the persistence models. However, I've found that the benefit of maintaining a good separation of concerns between the persistence layer and my domain models provides major benefits. 2.) The second method that I use is adding *to_json* and *from_json* static functions to my domain models or SQLAlchemy model objects (depending on how rich your domain model structure is and how big your project is). When I validate incoming JSON from the web (or any other service) I use Colander to validate the structure and turn the object to a dictionary. I will then use the *from_json* function to convert the object to the appropriate the persistence model or domain model. On the other hand, when I want to convert my domain object to JSON, I use the *to_json *function. This gives me the greatest control over the fields that I want to expose to JSON without needing an additional libraries or needing to define custom serializers/deserializers. Overall, I've found that's it's best to maintain distinct models for my persistence layer, domain model and view model even if it tends to be redundant. When I need to convert between two different object types, e.g. model view (JSON) to domain model, I simply add the static function to the object I need to convert to. These patterns have really helped me deal with a number of Pyramid applications that have grown quite large over the past few years. -Vincent On Tue, Jun 7, 2016 at 10:35 AM, Mikko Ohtamaa <[email protected]> wrote: > Hi, > > What I have seen happening that many people use __json__(self, request) > method on SQLAlchemy models. I find this dirty, as web subsystem should not > relevant to data persistency subsystem and there is a bleeding of > separation of concerns. > > I'd rather have one adapter per model which gives serialize/deserialize > process which permission support so that the same serializer could support > e.g. anonymous and authenticated use cases. > > In my ideal world > > - All data would be described as Colander > > - (semi-automatic) adapters would provide serializing between SQLAlchemy > model instances and Colander JSON schema > > - Python docstrings could be used do describe objects in Colander schema > > - Open API (swagger) schema could be generated from Colander schemas, thus > providing support for automatic Swagger client generation, API discovery > and such > > Some more related work > > https://github.com/stefanofontanelli/ColanderAlchemy > > http://websauna.org/docs/narrative/form/autoform.html (wrapper of above) > > https://pythonhosted.org/dictalchemy/ > > https://github.com/striglia/pyramid_swagger > > > > > On 7 June 2016 at 10:08, Iain Duncan <[email protected]> wrote: > >> Hi folks, I'm working on an internal framework using Pyramid, Colander, >> and SQLAlchemy, and it's for much more enterprisey apps than I have >> previously done. We're looking at having a full fledged service layer, and >> using the ZCA as a DI framework a fair bit. I'm hoping folks can share >> their opinions on what they've found the best place and way to convert from >> validated dicts (originating from JSON from angular.js) to SA mapped >> objects is. I'm using Colander to validate the incoming json, which might >> be nested two or three levels deep, so after Colander conversion I know the >> fields in the dicts are ok, but they are still just python dicts. >> >> In the past, I used formencode to do both validation and conversion, but >> in this case I'm hoping to keep SQLA logic and coupling to a business/model >> layer that is more insulated from the web request layer so it can be used >> without issue from non-web-request contexts (rabbitqm jobs, scripts, etc). >> So I'm imagining right now that outside this business/model layer the web >> controllers are dealing with json and validating with colander, inside the >> business/model we are dealing with either proxy objects to the model >> objects or direct model objects, and somewhere (?) we convert. >> >> Any suggestions on what people have found to be good strategies or tools >> (or reading!) for localizing and controlling the conversion from dicts to >> mapped objects with relationships would be much appreciated. Or suggestions >> that I'm just wrong and why. >> >> thanks. >> (apologies for cross post if you already read this on the SQLAlchemy >> list!) >> Iain >> >> -- >> You received this message because you are subscribed to the Google Groups >> "pylons-discuss" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> To post to this group, send email to [email protected]. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/pylons-discuss/CAN9NcLzWeQRVEAZhU1OZMwrc0fDiahMxQw1W1f6QtjfJe4__LQ%40mail.gmail.com >> <https://groups.google.com/d/msgid/pylons-discuss/CAN9NcLzWeQRVEAZhU1OZMwrc0fDiahMxQw1W1f6QtjfJe4__LQ%40mail.gmail.com?utm_medium=email&utm_source=footer> >> . >> For more options, visit https://groups.google.com/d/optout. >> > > > > -- > Mikko Ohtamaa > http://opensourcehacker.com > http://twitter.com/moo9000 > > -- > You received this message because you are subscribed to the Google Groups > "pylons-discuss" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To post to this group, send email to [email protected]. > To view this discussion on the web visit > https://groups.google.com/d/msgid/pylons-discuss/CAK8RCUv-p9jJhS%2BABxauZw3dc5QoY-voLfNVF7DYN6U1_BFodA%40mail.gmail.com > <https://groups.google.com/d/msgid/pylons-discuss/CAK8RCUv-p9jJhS%2BABxauZw3dc5QoY-voLfNVF7DYN6U1_BFodA%40mail.gmail.com?utm_medium=email&utm_source=footer> > . > > For more options, visit https://groups.google.com/d/optout. > -- Vincent Catalano Software Engineer and Web Developer, (520).603.8944 -- You received this message because you are subscribed to the Google Groups "pylons-discuss" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/pylons-discuss/CAEhnOsySv8PvOWUXkdNtrWqsHG3zVYvwWoWGt04HRAuh%3Db4GHw%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.
