I need to make a list property that will contain lists, something like:
db.ListProperty(list(str))
I know list(str) is not a supported value type so as I imagined I received a "ValueError" exception.
Thought maybe there is a creative idea out there of how to overcome this :)
Thanks!
You could use pickle to serialize your list and store it in a BlobProperty field.
Expanding on Adam's suggestion, you can push the pickling into its own Property class. Here is an example that handles validation, and converting the provided list into and out of a Blob type. The provided list can contain any data type or combination of datatypes, since it just stores a standard python list.
import pickle
class GenericListProperty(db.Property):
data_type = db.Blob
def validate(self, value):
if type(value) is not list:
raise db.BadValueError('Property %s must be a list, not %s.' % (self.name, type(value), value))
return value
def get_value_for_datastore(self, model_instance):
return db.Blob(pickle.dumps(getattr(model_instance,self.name)))
def make_value_from_datastore(self, value):
return pickle.loads(value)
You use it as you would any other property.
class ModelWithAGenericList(db.Model):
mylist = GenericListProperty()
class MainHandler(webapp.RequestHandler):
def get(self):
db.delete(ModelWithAGenericList.all())
m = ModelWithAGenericList(mylist = [[1,2,3],[4,5,6],6])
m.put()
m = ModelWithAGenericList.all().fetch(1)[0]
self.response.out.write(str(m.mylist))
# Outputs: [[1, 2, 3], [4, 5, 6], 6]
If your using Java you could store the list of lists as a blob (provided they are standard lists and their contents are serializable) but this does stop you being able to get datastore to searches on its contents.
// -----------------------------------------------
import java.io.Serializable;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.IOException;
import com.google.appengine.api.datastore.Blob;
Serializable s = (Serializable) myListOfLists;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try{
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(s);
oos.close();
}catch(IOException ioexception){
}
entity.setProperty("data", new Blob(baos.toByteArray()));
// -------------------------------------------
import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
import com.google.appengine.api.datastore.Blob;
ByteArrayInputStream bais = new ByteArrayInputStream(((Blob)e.getProperty("data")).getBytes());
try {
ObjectInputStream ois = new ObjectInputStream(bais);
myListOfLists = (List<List<String>>) ois.readObject();
} catch (IOException e1) {
} catch (ClassNotFoundException e1) {
}