首页 > 解决方案 > AWS SimpleDB 的棉花糖架构

问题描述

我正在尝试设置一些棉花糖类来简化从 AWS SimpleDB 服务中放置和获取记录的过程。

AWS 需要在此处的接口中解释的 put_record 中的名称、值对列表。我的用例不需要可选的 Replace 或 Expected 属性。

因此,我希望构建一些简化加载(_deserialize)和卸载(_serialize)的棉花糖模式。由于 SDB 是一个纯字符串数据库,我已经成功构建了几个字段编码器来序列化/反序列化各种整数、日期时间字段和布尔值到可以按字典顺序排序的字符串。例如,这是我的整数编码器/解码器:

class SDBNumberField(fields.Field):
"""
    Converts a python number into a padded string that is suitable for storage
    in Amazon SimpleDB and can be sorted lexicographically.

    Numbers are shifted by an offset so that negative numbers sort correctly. Once
    shifted, they are converted to zero padded strings.
    """

def __init__(self, padding=10, precision=2, offset=100, **kwargs):
    super().__init__(**kwargs)
    self.padding = padding
    self.precision = precision
    self.offset = offset

def _serialize(self, value, attr, obj, **kwargs):

    padding = self.padding
    if self.precision > 0 and self.padding > 0:
        # Padding shouldn't include decimal digits or the decimal point.
        padding += self.precision + 1
    return ('%%0%d.%df' % (padding, self.precision)) % (value + self.offset)

def _deserialize(self, value, attr, data, **kwargs):
    """
    Decoding converts a string into a numerical type then shifts it by the
    offset.
    """
    try:
        return float(value) - self.offset
    except ValueError as error:
        raise ValidationError("Number fields must contain only numbers: {}".format(value)) from error

当我有一个已知的名称/值对模式时,序列化/反序列化工作。

但是,我正在挂断的是提出一个通用类,它只是将转储上的标准字典转换为键/值对列表,因为有时我的键/值对在运行时之前是未知的。

我想看到的是这样的:

record_to_dump = {'Name': 'test', 'Attributes': {'key1': 'value1', 'key2': 'value2'}}
schema.dump(record_to_dump)
{"Name": "test",
 "Attributes": [{"Name": "key1", "Value" : "value1"}, {"Name": "key2", "Value": "value2"}]}
assert schema.load({"Name": "test",
 "Attributes": [{"Name": "key1", "Value" : "value1"}, {"Name": "key2", "Value": "value2"}]}) == record_to_dump

但是,我不确定如何设置类来处理从标准字典到接口所需的名称/值对列表的转换。

我已经尝试了几种方法,包括 fields.Method 以及用于序列化/反序列化的加载/卸载方法。我也尝试过使用 post_load 和 pre_dump 装饰器。我似乎缺少的是如何处理该字段是序列化的一种类型(字典)和反序列化的另一种类型(字典列表)的事实。

这种方法非常接近:

class SDBAttributesSchema(Schema):
    Attributes = fields.Method(serialize="_put_attributes", deserialize="_get_attributes")

    def _put_attributes(self, obj, **kwargs):
        return [{"Name": k, "Value": v} for k, v in obj.items()]

    def _get_attributes(self, obj, many=True):
        return {d['Name']: d["Value"] for d in obj}

但是,当我将它作为嵌套对象与另一个类放在一起时,它就会分崩离析:

class SDBItemSchema(Schema):
    Name = fields.Str()
    Attributes = fields.Nested(SDBAttributesSchema)

我想我很困惑:

给定上述所需的转储和加载记录,您将如何处理类模式对象?

标签: pythonjsonamazon-web-servicesmarshmallowamazon-simpledb

解决方案


推荐阅读