user1055761
user1055761

Reputation: 1081

Appengine Datastore Propery fromString () method

Is there a generic method to set a property in datastore entity instance from a string such that it carries out the underlying conversion based on the Property type.

person = Person ()
person.setattr("age", "26") # age is an IntegerProperty
person.setattr("dob", "1-Jan-2012",[format]) # dob is a Date Property

This is easy to write, but this is a very common use case and was wondering whether the Datastore Python API has any provision.

(Sorry if this is a pedestrian question, I am relatively new to Appengine and could not find thru the docs).

Appreciate your help.

Upvotes: 1

Views: 103

Answers (1)

voscausa
voscausa

Reputation: 11706

I had a couple of days ago the same question for another usecase. To solve it I created a list of property types, to do the conversion I needed. This solution makes use of an undocumented db function and the internals of the db.Model class. Maybe there is a better solution.

from google.appengine.ext import db
kind = 'Person'
models_module = { 'Person' : 'models'}       # module to import the model kind from

model_data_types = {}                        # create a dict of properties, like DateTimeProperty, IntegerProperty
__import__(models_module[kind], globals(), locals(), [kind], -1) 
model_class = db.class_for_kind(kind)        # not documented
for key in model_class._properties :         # the internals of the model_class object
    model_data_types[key] = model_class._properties[key].__class__.__name__

To convert your strings, you can create a class with string conversion functions like :

class StringConversions(object)

    def IntegerProperty(self, astring):

        return int(astring)     

    def DateTimeProperty(self, astring):

        # do the conversion here
        return ....

And use it like :

property_name = 'age'
astring = '26'

setattr(Person, property_name, getattr(StringConversions,  model_data_types[property_name] )(astring) ) 

UPDATE:

There is no documentation for : db.class_for_kind(kind) But there is better solution. Replace these two lines :

__import__(models_module[kind], globals(), locals(), [kind], -1) 
model_class = db.class_for_kind(kind)        # not documented

With :

module = __import__(models_module[kind], globals(), locals(), [kind], -1) 
model_class = getattr(module, kind)

Upvotes: 2

Related Questions