【问题标题】:GAE converting dictionary to NDB datastore entityGAE 将字典转换为 NDB 数据存储实体
【发布时间】:2013-08-11 12:57:00
【问题描述】:

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

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

我的步骤是:

  1. 获取字典。
  2. 通过读取模型的类dict来验证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 类,所以字典中任何额外的属性都会被存储。

如何检查这些特定类型?

【问题讨论】:

  • 你为什么不使用 populate() 方法developers.google.com/appengine/docs/python/ndb/…。此外,一个实例列出了_properties 中的所有属性
  • @TimHoffman 我想我错过了。现在正在尝试。大概就是我需要的。谢谢,正如我所说,我知道我错过了一些东西。
  • @TimHoffman 我仍然存在的唯一问题是,因为我使用的是 expando 模型,所以额外的 dict 键值被写入数据存储区。如果字典中存在相同的键,则除了类方法和属性之外,还会创建一个 colsion
  • 好的,这是您应该包含的一些信息。看看使用 _properties 来驱动属性迭代器而不是管道。
  • @TimHoffman 再次感谢。明白了,看答案

标签: python google-app-engine entity app-engine-ndb


【解决方案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

【讨论】:

    【解决方案2】:

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

    我也没有使用填充,因为我发现它与传递在模型的构造函数中解包的有效 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
    

    【讨论】:

    • 覆盖dict 关键字不是一个好习惯。也许用 data_dict 之类的东西代替它?
    • 这个metot遇到整数prop时会抛出错误
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-11
    • 1970-01-01
    • 2016-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多