数据存储列表

时间:2010-01-08 14:59:44

标签: google-app-engine google-cloud-datastore

我需要创建一个包含列表的列表属性,例如: db.ListProperty(列表(STR))

我知道list(str)不是受支持的值类型,所以我想我收到了一个“ValueError”异常。 想到也许有一个创造性的想法如何克服这个:)

谢谢!

3 个答案:

答案 0 :(得分:6)

扩展Adam的建议,你可以将酸洗推入自己的Property类。下面是一个处理验证,并将提供的列表转换为Blob类型和从Blob类型转换出来的示例。提供的列表可以包含任何数据类型或数据类型的组合,因为它只存储标准的python列表。

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)

您可以像使用任何其他财产一样使用它。

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]

答案 1 :(得分:1)

您可以使用pickle序列化列表并将其存储在BlobProperty字段中。

答案 2 :(得分:0)

如果你使用Java,你可以将列表列表存储为blob(前提是它们是标准列表,并且它们的内容是可序列化的)但这确实会阻止你能够获取数据存储来搜索其内容。

// -----------------------------------------------
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) {

}

// ----------------------------------------------- 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) { }