Могу ли я сохранить словарь Python в хранилище данных Google BigTable, не сериализовав его явно? - PullRequest
1 голос
/ 23 декабря 2009

У меня есть словарь Python, который я хотел бы сохранить в хранилище данных Google BigTable (это атрибут класса db.Model).

Есть ли простой способ сделать это? то есть используя db.DictionaryProperty? Или я должен использовать pickle для сериализации моего словаря? Мой словарь относительно прост. Он состоит из строк в качестве ключей, но может также содержать словари для некоторых ключей. Например:

{ 
    'myKey' : 100,
    'another' : 'aha',
    'a sub dictionary' : { 'a': 1, 'b':2 }
}

PS: я хотел бы сериализовать как двоичный файл, а не текст, если это возможно.

Ответы [ 3 ]

8 голосов
/ 23 декабря 2009

Вот другой подход :

class DictProperty(db.Property):
  data_type = dict

  def get_value_for_datastore(self, model_instance):
    value = super(DictProperty, self).get_value_for_datastore(model_instance)
    return db.Blob(pickle.dumps(value))

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

  def default_value(self):
    if self.default is None:
      return dict()
    else:
      return super(DictProperty, self).default_value().copy()

  def validate(self, value):
    if not isinstance(value, dict):
      raise db.BadValueError('Property %s needs to be convertible '
                             'to a dict instance (%s) of class dict' % (self.name, value))
    return super(DictProperty, self).validate(value)

  def empty(self, value):
    return value is None
1 голос
/ 23 декабря 2009

Я полагаю, что когда вам нужно быть в состоянии прийти к диктату, это все сразу? Вам не нужно получать значения изнутри dict, пока он находится в хранилище данных?

Если это так, вам придется сериализовать, но не нужно использовать рассол; вместо этого мы используем simplejson. Затем получение просто переопределить toBasicType (), примерно так:

класс MyModel (db.Model): #define некоторые свойства, включая «data», который является TextProperty, содержащим biggish dict def toBasicType (self): return {'metadata': self.getMetadata (), 'data': simplejson.loads (self.data)}

Создание включает вызов MyModel (..., simplejson.dumps (data), ...).

Если вы уже мариноваете, это может быть вашим лучшим выбором, но simplejson работает очень хорошо для нас.

1 голос
/ 23 декабря 2009

Я думаю, что вы не можете избежать сериализации своих объектов.

Я бы определил следующую модель для хранения каждой пары ключ-значение:

class DictModel(db.Model):
    value = db.TextProperty()

Чтобы сохранить в хранилище данных, я бы использовал:

def set_value(key, value):
    key = DictModel(value=pickle.dumps(value), key_name=key)
    key.save()
    return key

И для извлечения данных:

def get_value(key):
    return pickle.loads(DictModel.get_by_key_name(key).value)
...