在GAE存储字典列表

3 投票
3 回答
2523 浏览
提问于 2025-04-16 16:55

我有一个大约20个对象的列表,每个对象都有一个包含10个字典的列表。
我想把每个对象的这10个字典列表存储到GAE(谷歌应用引擎)上;但我觉得我写的代码可能不太对,无法正确存储这些信息到GAE。
这是我现在的代码:

class Tw(db.Model):
  tags = db.ListProperty()
  ip = db.StringProperty()

在我的主要请求处理器中,我有以下内容:

for city in lst_of_cities: # this is the list of 20 objects
  dict_info = hw12.twitter(city) # this is the function to get the list of 10 dictionaries for each object in the list
  datastore = Tw() # this is the class defined for db.model
  datastore.tags.append(dict_info) # 
  datastore.ip = self.request.remote_addr
datastore.put()

data = Data.gql("") #data entities we need to fetch

我不确定这段代码是否正确。如果有人能帮忙就太好了,非常感谢。

3 个回答

4

自从这段话写成以来,App Engine推出了他们实验性的“ndb” Python数据库模型,里面特别有一个JsonProperty,这个功能基本上可以直接实现你想要的效果。

不过,你需要使用App Engine的Python 2.7版本,这个版本现在还不完全适合生产环境,但最近看起来挺稳定的。GvR本人似乎也在写很多代码,这对代码质量是个好兆头。我打算在今年的某个时候把它用在生产环境中……

4

欢迎来到Stack Overflow!

我发现了几个问题:

  1. 字典这种数据类型在App Engine的属性中是不能使用的。
  2. 你只保存了最后一个实体,之前的都被丢掉了。
  3. 你使用了一个列表属性,但你不是把字典中的每个元素都添加进去,而是一次性把整个列表添加上去。

因为你不能直接把字典存储在属性里,所以需要把它转换成其他格式,比如JSON或者pickle。下面是一个使用pickle的修改示例:

from google.appengine.ext import db
import pickle

class Tw(db.Model):
  tags = db.BlobProperty()
  ip = db.StringProperty()

entities = []
for city in lst_of_cities:
  dict_info = hw12.twitter(city)
  entity = Tw()
  entity.tags = db.Blob(pickle.dumps(dict_info))
  entity.ip = self.request.remote_addr
  entities.append(entity)

db.put(entities)

当你稍后获取这个实体时,可以用pickle.loads(entity.tags)来取出你的字典列表。

4

当我处理一些Google App Engine不直接支持的数据类型,比如字典或者自定义数据类型时,我通常会使用一个很方便的东西叫做 PickleProperty

from google.appengine.ext import db
import pickle

class PickleProperty(db.Property):
    def get_value_for_datastore(self, model_instance):
        value = getattr(model_instance, self.name, None)
        return pickle.dumps(value)

    def make_value_from_datastore(self, value):
        return pickle.loads(value)

在你的 commons.py 模块中声明了 PickleProperty 类之后,你就可以用它来存储你的自定义数据,像这样:

from google.appengine.ext import db
from commons import PickleProperty

class Tw(db.Model):
  tags = PickleProperty()
  ip = db.StringProperty()

entities = []
for city in lst_of_cities:
  dict_info = hw12.twitter(city)
  entity = Tw()
  entity.tags = dict_info
  entity.ip = self.request.remote_addr
  entities.append(entity)

db.put(entities)

要把数据取回来,可以这样做:

entity.tags

撰写回答