Question

I want to be able to take a dynamically created string, say "Pigeon" and determine at runtime whether Google App Engine has a Model class defined in this project named "Pigeon". If "Pigeon" is the name of a existant model class, I would like to then get a reference to the Pigeon class so defined.

Also, I don't want to use eval at all, since the dynamic string "Pigeon" in this case, comes from outside.

Was it helpful?

Solution

There's two fairly easy ways to do this without relying on internal details:

Use the google.appengine.api.datastore API, like so:

from google.appengine.api import datastore

q = datastore.Query('EntityType')
if q.get(1):
  print "EntityType exists!"

The other option is to use the db.Expando class:

def GetEntityClass(entity_type):
  class Entity(db.Expando):
    @classmethod
    def kind(cls):
      return entity_type
  return Entity

cls = GetEntityClass('EntityType')
if cls.all().get():
  print "EntityType exists!"

The latter has the advantage that you can use GetEntityClass to generate an Expando class for any entity type, and interact with it the same way you would a normal class.

OTHER TIPS

You could try, although probably very, very bad practice:

def get_class_instance(nm) :
    try :
        return eval(nm+'()')
    except :
        return None

Also, to make that safer, you could give eval a locals hash: eval(nm+'()', {'Pigeon':pigeon})

I'm not sure if that would work, and it definitely has an issue: if there is a function called the value of nm, it would return that:

def Pigeon() :
    return "Pigeon"
print(get_class_instance('Pigeon')) # >> 'Pigeon'

EDIT: Another way of doing it is possibly (untested), if you know the module:
(Sorry, I keep forgetting it's not obj.hasattr, its hasattr(obj)!)

import models as m
def get_class_instance(nm) :
    if hasattr(m, nm) :
        return getattr(m, nm)()
    else : return None

EDIT 2: Yes, it does work! Woo!

Actually, looking through the source code and interweb, I found a undocumented method that seems to fit the bill.

from google.appengine.ext import db

key = "ModelObject" #This is a dynamically generated string

klass = db.class_for_kind(key)

This method will throw a descriptive exception if the class does not exist, so you should probably catch it if the key string comes from the outside.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top