Python GAE将字典转换为NDB数据存储实体
我想就我正在尝试解决的一项小任务询问一些指导原则。 我正在试验一个使用JSON数据保存实体的小应用程序 我知道,只需创建模型,就可以轻松地将dict转换为实体,但我正在尝试构建一种更通用的方法,将任何dict转换为实体 我的步骤是:Python GAE将字典转换为NDB数据存储实体,python,google-app-engine,entity,app-engine-ndb,Python,Google App Engine,Entity,App Engine Ndb,我想就我正在尝试解决的一项小任务询问一些指导原则。 我正在试验一个使用JSON数据保存实体的小应用程序 我知道,只需创建模型,就可以轻松地将dict转换为实体,但我正在尝试构建一种更通用的方法,将任何dict转换为实体 我的步骤是: 拿到口述 通过读取模型的类来验证dict键是否与实体的模型定义相对应。dict 尝试在模型类构造函数中解压缩已验证的属性(创建模型实例) 归还它 到目前为止,我还行,但缺乏python知识,这要么限制了我,要么让我困惑。 也许我忘记了或者不知道更简单的方法 这就是:
@classmethod
def entity_from_dict(cls, parent_key, dict):
valid_properties = {}
logging.info(cls.__dict__)
for property,value in dict.iteritems():
if property in cls.__dict__: # should not iterate over functions, classmethods, and @property
logging.info(cls.__dict__[property]) # this outputs eg: StringProperty('title', required=True)
logging.info(type(cls.__dict__[property])) #this is more interesting <class 'google.appengine.ext.ndb.model.StringProperty'>
valid_properties.update({property: value})
# Update the id from the dict
if 'id' in dict: # if not creating a new entity
valid_properties['id'] = dict['id']
# Add the parent
valid_properties['parent'] = parent_key
#logging.info(valid_properties)
try:
entity = cls(**valid_properties)
except Exception as e:
logging.exception('Could not create entity \n' + repr(e))
return False
return entity
@classmethod
来自dict的def实体(cls、父项、dict):
有效的_属性={}
logging.info(cls.\u dict\u)
对于属性,dict.iteritems()中的值:
cls中的if属性。dict:#不应迭代函数、类方法和@property
logging.info(cls.u dict___[property])#此输出例如:StringProperty('title',required=True)
logging.info(类型(cls.\uu dict\uuuu[property]))#这更有趣
有效的_属性。更新({property:value})
#从dict更新id
如果dict中的'id':#如果未创建新实体
有效的_属性['id']=dict['id']
#添加父级
有效的\u属性['parent']=父\u键
#logging.info(有效的\u属性)
尝试:
实体=cls(**有效的属性)
例外情况除外,如e:
logging.exception('无法创建实体\n'+repr(e))
返回错误
返回实体
我的问题是,我只想验证ndb。属性,而不是@classmethods,@property,因为这会导致冲突
我还使用expando类,所以dict中的任何额外属性都会被存储
如何对照这些特定类型进行检查 正如@Tim Hoffman使用Ndb模型的
\u属性
提出的那样解决了这个问题。
我不知道的一件事是,通过\u属性
我可以获得模型定义属性,我认为它只会返回实例属性:-)
另外,我没有使用populate,因为我发现它的作用与传递模型构造函数中解包的有效dict相同;-)
这就是:
@classmethod
def entity_from_dict(cls, parent_key, data_dict):
valid_properties = {}
for cls_property in cls._properties:
if cls_property in data_dict:
valid_properties.update({cls_property: data_dict[cls_property]})
#logging.info(valid_properties)
# Update the id from the data_dict
if 'id' in data_dict: # if creating a new entity
valid_properties['id'] = data_dict['id']
# Add the parent
valid_properties['parent'] = parent_key
try:
entity = cls(**valid_properties)
except Exception as e:
logging.exception('Could not create entity \n' + repr(e))
return False
return entity
python中的JSON转储方法在将模型转换为JSON进行导出时使用,该方法将非字符串转换为字符串。因此,Jimmy Kane方法由于模型不兼容而抛出错误。为了避免这个问题,我更新了他的方法,并添加了一个名为
prop_literal
的方法,用于将封装在字符串中的非字符串字符转换为其文本类型
我还添加了entity.put()
以将实体添加到数据存储中,因为目标是:)
为什么不使用populate()方法呢。此外,一个实例列出了
\u properties
@TimHoffman中的所有属性,我想我错过了。正在尝试。也许这就是我需要的。谢谢,正如我所说的,我知道我遗漏了一些东西。@TimHoffman我唯一的问题是,因为我使用的是expando模型,所以额外的dict键值会写入数据存储。Ass以及classmethods和属性创建了一个colion,如果dictOK中存在相同的键,那么这是您应该包含的一些信息。看看如何使用_属性来驱动属性迭代器,而不是管道。@TimHoffman再次感谢。明白了,请参见答案覆盖dict
关键字不是一个好的做法。也许可以用类似data_dict的东西来替换它?当遇到整数属性时,这个metot会抛出错误
def prop_literal(prop_type,prop_val):
"""
Convert non-string encapsulated in the string into literal type
"""
if "Integer" in prop_type:
return int(prop_val)
elif "Float" in prop_type:
return float(prop_val)
elif "DateTime" in prop_type:
# bos gecsin neticede locale
return None
elif ("String" in prop_type) or ("Text" in prop_type):
return prop_val
elif "Bool" in prop_type:
return True if prop_val == True else False
else:
return prop_val
def entity_from_dict(cls, parent_key, data_dict):
valid_properties = {}
for cls_property in cls._properties:
if cls_property in data_dict:
prop_type = str(cls._properties[cls_property])
# logging.info(prop_type)
real_val = prop_literal(prop_type,data_dict[cls_property])
try:
valid_properties.update({cls_property: real_val})
except Exception as ex:
# logging.info("Veri aktariminda hata:"+str(ex))
else:
# logging.info("prop skipped")
#logging.info(valid_properties)
# Update the id from the data_dict
if 'id' in data_dict: # if creating a new entity
valid_properties['id'] = data_dict['id']
# Add the parent
valid_properties['parent'] = parent_key
try:
entity = cls(**valid_properties)
logging.info(entity)
entity.put()
except Exception as e:
logging.exception('Could not create entity \n' + repr(e))
return False
return entity