2

我想就我正在尝试解决的一项小任务询问一些指导方针。我正在试验一个使用 JSON 数据保存实体的小应用程序。

我知道您可以通过创建模型轻松地将字典转换为实体,但是,我正在尝试构建一种更通用的方法,将任何字典转换为实体。

我的步骤是:

  1. 得到字典。
  2. 通过读取类来验证 dict 键是否对应于实体模型定义。模型的字典
  3. 尝试在模型类构造器中解压已验证的属性(创建模型实例)
  4. 把它返还。

到目前为止我还好,但缺乏我的 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 类,所以字典中任何额外的属性都会被存储。

如何检查这些特定类型?

4

2 回答 2

2

按照@Tim Hoffman 建议使用._propertiesNdb 模型解决它。我不知道的是,通过._properties我可以获得模型定义属性,我认为它只会返回实例属性:-)。

我也没有使用填充,因为我发现它与传递在模型的构造函数中解包的有效字典一样;-)

所以这里是:

@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
于 2013-08-11T14:42:24.207 回答
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
于 2018-10-12T08:39:57.160 回答