I'm using SQLAlchemy extension with Flask. While serializing my models (which are also used for database operations) using jsonpickle, I want some specific attributes to be ignored. Is there a way that allows me to set those rules?
SQLAlchemy adds an attribute named _sa_instance_state
to the object. In a word, I do not want this field to be in the JSON output.
You cannot tell the default class pickler to ignore something, no.
jsonpickle
does support the pickle
module __getstate__
and __setstate__
methods. If your classes implement those two methods, whatever is returned is then used by jsonpickle
to represent the state instead. Both methods do need to be implemented.
If __getstate__
is not implemented, jsonpickle
uses the __dict__
attribute instead, so your own version merely needs to use that same dictionary, remove the _sa_instance_state
key and you are done:
def __getstate__(self):
state = self.__dict__.copy()
del state['_sa_instance_state']
return state
def __setstate__(self, state):
self.__dict__.update(state)
Whatever __getstate__
returns will be processed further, recursively, there is no need to worry about handling subobjects there.
If adding __getstate__
and __setstate__
is not an option, you can also register a custom serialization handler for your class; the disadvantage is that while __getstate__
can get away with just returning a dictionary, a custom handler will need to return a fully flattened value.
This one will help others to get their task done:
Make a class like this one in a package like your custom jsonpickle
package:
class SetGetState:
def __getstate__(self):
state = self.__dict__.copy()
try:
class_name = '_' + self.__class__.__name__ + '__'
new_items = {key:value for key, value in state.items() if class_name not in key}
return new_items
except KeyError:
pass
return state
And inherit this one in the class requires no private property serialization
class Availability(jsonpickle.SetGetState):
pass