tagtraum
tagtraum

Reputation: 515

Using Custom Property in Google App Engine

I'm using google app engine/python. And I have created a custom datatype and property. But I have problem using it. This is my definition

from datetime import datetime

class MyDateTime(datetime):
    def __str__(self):
        return self.strftime("%Y-%m-%d %H:%M")

class MyDateTimeProperty(db.Property):
    # specify datatype
    data_type = MyDateTime

    # For writing to datastore.
    def get_value_for_datastore(self, model_instance):
        return super(MyDateTimeProperty, self).get_value_for_datastore(model_instance)

    # For reading from datastore.
    def make_value_from_datastore(self, value):
        return super(MyDateTimeProperty, self).validate(value)

class MyClass(db.Model):
    date = MyDateTimeProperty()

and this is how I use it:

obj = MyClass(date=MyDateTime(2011,1,1))
obj.put()

and I got the following error message:

Traceback (most recent call last):
  File "C:\Program Files\Google\google_appengine\google\appengine\ext\admin\__init__.py", line 295, in post
    exec(compiled_code, globals())
  File "<string>", line 23, in <module>
  File "C:\Program Files\Google\google_appengine\google\appengine\ext\db\__init__.py", line 1052, in put
    self._populate_internal_entity()
  File "C:\Program Files\Google\google_appengine\google\appengine\ext\db\__init__.py", line 1020, in _populate_internal_entity
    self._entity = self._populate_entity(_entity_class=_entity_class)
  File "C:\Program Files\Google\google_appengine\google\appengine\ext\db\__init__.py", line 1092, in _populate_entity
    self._to_entity(entity)
  File "C:\Program Files\Google\google_appengine\google\appengine\ext\db\__init__.py", line 1005, in _to_entity
    self.__set_property(entity, prop.name, prop.get_value_for_datastore(self))
  File "C:\Program Files\Google\google_appengine\google\appengine\ext\db\__init__.py", line 995, in __set_property
    entity[name] = datastore_value
  File "C:\Program Files\Google\google_appengine\google\appengine\api\datastore.py", line 881, in __setitem__
    datastore_types.ValidateProperty(name, value)
  File "C:\Program Files\Google\google_appengine\google\appengine\api\datastore_types.py", line 1477, in ValidateProperty
    'Unsupported type for property %s: %s' % (name, v.__class__))
BadValueError: Unsupported type for property date: <class '__main__.MyDateTime'>

I've searched for solution for a while and could not solve it. Thanks in advance if anyone knows how to fix it.


thanks for the answer. I figured out that the prime problem is that custom data type can't go into datastore, so I need to wrap/unwrap the custom datatype to/from usual datatype using get_value_for_datastore and make_value_from_datastore

this is my modified property definition:

class MyDateTimeProperty(db.Property):
    # specify datatype
    data_type = MyDateTime

    # For writing to datastore.
    def get_value_for_datastore(self, model_instance):
        date = super(MyDateTimeProperty, self).get_value_for_datastore(model_instance)
        return datetime(date.year, date.month, date.day, date.hour, date.minute)

    # For reading from datastore.
    def make_value_from_datastore(self, value):
        if value is None:
            return None
        return MyDateTime(value.year, value.month, value.day, value.hour, value.minute)

The key is, using get_value_for datastore to change an unstorable MyDateTime object to storable datetime object, and make_value_from_datastore vice versa.

Upvotes: 4

Views: 793

Answers (1)

Wooble
Wooble

Reputation: 89857

Your Property subclass needs to define a validate() method if its datatype isn't one of the defined datastore data types that the default validator knows about. There's an example validator method in this article.

Upvotes: 3

Related Questions