views:

63

answers:

3

Using datastore framework of appengine, what's the pythonic way to make persistent a {}?

+1  A: 

You should store it using pickle.dumps and retrieve it using pickle.loads

see http://docs.python.org/library/pickle.html

Xavier Combelle
A: 

I think there are 2 options.

  1. Using expando. You can store anything in that as long as you omit the reserved fields:

    class SomeModel(db.Expando):
        pass
    
    
    your_model = SomeModel()
    for k, v in your_dict.iteritems():
        setattr(your_model, k, v)
    

    It might be possible to use your_model.__dict__.update(your_dict) but I'm not sure about that.

  2. Store it in a textfield using pickle:

    class SomeModel(db.Model):
        pickled_data = db.Blob()
    
    
    your_model = SomeModel()
    your_model.pickled_data = pickle.dumps(your_dict)
    
WoLpH
tnx for link!http://github.com/Arachnid/aetycoon/blob/master/__init__.py
Altraqua
If you use the custom property, you don't need to explicitly unpickle the value every time you want to read it. No problem re. the link :)
hawkettc
Indeed, your option is much more elegant :) +1
WoLpH
+2  A: 

You would only need to use the expando option if you intend to query on the individual dictionary elements.

Assuming you don't want to do this, then you can use a custom property -

class ObjectProperty(db.Property):
  data_type = db.Blob

  def get_value_for_datastore(self, model_instance):
    value = self.__get__(model_instance, model_instance.__class__)
    pickled_val = pickle.dumps(value)
    if value is not None: return db.Blob(pickled_val)

  def make_value_from_datastore(self, value):
    if value is not None: return pickle.loads(str(value))

  def default_value(self):
    return copy.copy(self.default)

Note that the above property def I got from some code that Nick Johnson produced. It's a project on git hub, and contains a number of other custom properties.

hawkettc