我想问一些我正试图解决的小任务的指导方针。 我正在尝试使用JSON数据保存实体的小应用程序。
我知道你可以通过创建模型轻松地将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
我的问题是我只想验证ndb。属性而不是@classmethods,@ property也因为这会导致冲突。
我也在使用expando类,因此dict中任何额外的属性都会被存储。
如何检查这些特定类型?
答案 0 :(得分:2)
解决它@Tim Hoffman建议使用Ndb模型的._properties
。
我不知道的一件事是通过._properties
我可以得到模型定义属性,我认为它只会返回实例属性:-)。
另外我没有使用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
答案 1 :(得分:1)
在将模型转换为JSON进行导出的过程中,我们使用python中的JSON转储方法将非字符串转换为字符串。因此,Jimmy Kane方法由于模型不兼容而引发错误。为避免此问题,我更新了他的方法,并添加了一个名为prop_literal
的方法,该方法仅用于将封装在字符串中的非字符串字符转换为其文字类型。
我还添加了entity.put()
以将实体添加到数据存储区,因为目的是:)
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