动态创建Google数据存储区的类属性

时间:2013-10-14 03:10:08

标签: python google-cloud-datastore

我想得到类似的结果:

class MyClass(db.Model):
    field=db.IntegerProperty()

即,此类的对象应在其属性列表中包含field

o=MyClass()
o.properties()

但是,这些字段应根据其名称和类型的定义动态创建,如下例所示:

class MyClass(db.Model):
    def __init__(self,*args,**kwargs):
        defs={'field':'d','otherfield':'s'} #'d' for integer, 's' for string
        for key in defs:
            typeof=defs[key]
            val=db.StringProperty() if typeof=='s' else db.IntegerProperty()
            #tried these lines below... but properties() are still empty :|
            setattr(self, key, val)
            setattr(self.__class__, key, val)
            setattr(self.__class__, key, property(lambda self: self.__dict__[key]))
            self.__dict__.update({key:val})
        db.Model.__init__(self,*args,**kwargs)

setattr行都没有工作(它们创建字段但不创建属性);对象中的属性列表仍为空,因此我似乎无法在db.GqlQuery()中使用此类对象。我不想使用“Expando”模型,因为在我的情况下,字段列表及其类型是已知的并且是常量。使用eval可能会完成这项工作,但会很难看。

我相信启动帖子的两条简单线条可以通过简单的方式动态实现......我必须找不到一些明显的解决方案。

1 个答案:

答案 0 :(得分:0)

据我所知,你不能做这样的事情。这里有一些问题,db.WhateverProperty()设计在上,而不是在实例上。就像常规属性一样,当它们附加到实例而不是类时,它们没有很多意义。我认为您最好的选择是在ast.literal_eval内容上使用json.loadsStringProperty并将错误处理为字符串。

或者,您可以在模型上有2个属性/属性,然后您可以编写基于类型委托给正确方法的访问方法。

如果您不反对使用ndb.Model,您可能可以使用ndb.JsonProperty - 但我不确定如何将其编入索引以供查询使用。