- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在编写一个 REST API,它将多个复杂对象存储到 AWS DynamoDB,然后根据请求检索它们、对它们执行计算并返回结果。这是大量提取、简化、重命名的伪代码。
class Widget:
def __init__(self, height, weight):
self.height = height
self.weight = weight
class Machine:
def __init__ (self, widgets):
self.widgets = widgets
def useful_method ():
return "something great"
class WidgetSchema (Schema):
height = fields.Decimal()
weight = fields.Decimal()
@post_load
def make_widget (self, data):
return Widget(*data)
class MachineSchema (Schema):
widgets = fields.List(fields.Nested(WidgetSchema))
def make_machine (self, data):
return Machine(*data)
app = Flask(__name__)
dynamodb = boto3.resource("dynamodb", ...)
@app.route("/machine/<uuid:machine_id>", methods=['POST'])
def create_machine(machine_id):
input_json = request.get_json()
validated_input = MachineSchema().load(input_json)
# NOTE: validated_input should be a Python dict which
# contains Decimals instead of floats, for storage in DynamoDB.
validate_input['id'] = machine_id
dynamodb.Table('machine').put_item(Item=validate_input)
return jsonify({"status", "success", error_message = ""})
@app.route("/machine/<uuid:machine_id>/compute", methods=['GET'])
def get_machine(machine_id):
result = dynamodb.Table('machine').get_item(Key=machine_id)
return jsonify(result['Item'])
@app.route("/machine/<uuid:machine_id>/compute", methods=['GET'])
def compute_machine(machine_id):
result = dynamodb.Table('machine').get_item(Key=machine_id)
validated_input = MachineSchema().load(result['Item'])
# NOTE: validated_input should be a Machine object
# which has made use of the post_load
return jsonify(validated_input.useful_method())
问题是我需要让我的棉花糖模式承担双重职责。对于初学者来说,在 create_machine 函数中,我需要架构来确保调用我的 REST API 的用户向我传递了一个正确形成的对象,没有额外的字段并且满足所有必需的字段等。我需要确保我没有存储毕竟数据库中存在无效垃圾。它还需要递归地抓取输入 JSON 并将所有 JSON 值转换为正确的类型。例如,Dynamo 不支持 float ,因此它们需要是小数,如下所示。这是棉花糖做的很容易的事情。如果没有 post_load,这正是将生成的 valid_input。
该架构的第二个任务是它需要获取从 DynamoDB 检索的 Python 对象,该对象看起来几乎与用户输入 JSON 完全一样,除了浮点是小数之外,并且转换将其放入我的 Python 对象、Machine 和 Widget 中。这是我需要再次读取对象的地方,但这次使用后加载来创建对象。然而,在这种情况下,我不希望我的数字是小数。我希望它们成为标准的 Python float 。
我可以为此编写两个完全不同的棉花糖模式并清楚地完成它。一种是用小数表示高度和体重,一种是用 float 。一个可以对每个对象进行后期加载,有些则没有。但编写两个相同的模式是一个巨大的痛苦。我的模式定义有几百行长。通过后加载继承数据库版本似乎不是正确的方向,因为我需要更改任何字段。嵌套以指向正确的类。例如,即使我从 MachineSchema 继承了 MachineSchemaDBVersion,并添加了 post_load,MachineScehemaDBVersion 仍然会引用 WidgetScehema,而不是 WidgetSchema 的某些数据库版本,除非我也覆盖了 widgets 字段。
我可能会派生自己的 Schema 对象,并传递一个标志来判断我们是否处于数据库模式。
人们通常如何处理希望将 REST API 输入或多或少直接存储到 DynamoDB 并进行一些验证,然后使用该数据构建 Python 对象进行计算的问题?
我尝试过的方法是让我的架构始终实例化我的 Python 对象,然后使用完全构造的对象中的转储将它们哑巴到数据库中。问题在于计算库的对象(在我的示例 Machine 或 Widget 中)不具有我需要存储在数据库中的所有必需字段,例如 ID、名称或描述。这些对象是专门为进行计算而创建的。
最佳答案
我最终找到了解决这个问题的方法。实际上,我所做的就是生成专门用于从 DynamoDB 转换为 Python 对象的 Marshmallow 架构。所有 Schema 类都具有转换为 Python 对象的 @post_load 方法,并且所有字段都标有它们在 Python 世界(而不是数据库世界)中所需的类型。
当验证来自 REST API 的输入并确保不允许错误数据进入数据库时,我调用 MySchema().validate(input_json)
,检查是否存在错误,如果没有,则将 input_json 转储到数据库中。
这只剩下一个额外的问题,即需要清理 input_json 才能进入数据库,这是我之前使用 Marshmallow 所做的。不过,这也可以通过调整我的 JSON 解码器以从 float 读取小数来轻松完成。
总而言之,我的 JSON 解码器正在递归地遍历数据结构并将 Float 转换为 Decimal,与 Marshmallow 分开。 Marshmallow 对每个对象的字段运行验证,但仅检查结果是否有错误。然后原始输入被转储到数据库中。
我需要添加这一行来转换为十进制。
app.json_decoder = partial(flask.json.JSONDecoder, parse_float=decimal.Decimal)
我的创建函数现在看起来像这样。请注意,由我更新的 JSON 解码器解析的原始 input_json 是如何直接插入到数据库中的,而不是从 Marshmallow 输出的任何数据。
@app.route("/machine/<uuid:machine_id>", methods=['POST'])
def create_machine(machine_id):
input_json = request.get_json() # Already ready to be DB input as is.
errors = MachineSchema().validate(input_json)
if errors:
return jsonify({"status": "failure",message = dumps(errors)})
else:
input_json['id'] = machine_id
dynamodb.Table('machine').put_item(Item=input_json)
return jsonify({"status", "success", error_message = ""})
关于python - 如何构建 JSON 架构以验证 DynamoDB 和 REST API?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53730517/
我正在处理一组标记为 160 个组的 173k 点。我想通过合并最接近的(到 9 或 10 个组)来减少组/集群的数量。我搜索过 sklearn 或类似的库,但没有成功。 我猜它只是通过 knn 聚类
我有一个扁平数字列表,这些数字逻辑上以 3 为一组,其中每个三元组是 (number, __ignored, flag[0 or 1]),例如: [7,56,1, 8,0,0, 2,0,0, 6,1,
我正在使用 pipenv 来管理我的包。我想编写一个 python 脚本来调用另一个使用不同虚拟环境(VE)的 python 脚本。 如何运行使用 VE1 的 python 脚本 1 并调用另一个 p
假设我有一个文件 script.py 位于 path = "foo/bar/script.py"。我正在寻找一种在 Python 中通过函数 execute_script() 从我的主要 Python
这听起来像是谜语或笑话,但实际上我还没有找到这个问题的答案。 问题到底是什么? 我想运行 2 个脚本。在第一个脚本中,我调用另一个脚本,但我希望它们继续并行,而不是在两个单独的线程中。主要是我不希望第
我有一个带有 python 2.5.5 的软件。我想发送一个命令,该命令将在 python 2.7.5 中启动一个脚本,然后继续执行该脚本。 我试过用 #!python2.7.5 和http://re
我在 python 命令行(使用 python 2.7)中,并尝试运行 Python 脚本。我的操作系统是 Windows 7。我已将我的目录设置为包含我所有脚本的文件夹,使用: os.chdir("
剧透:部分解决(见最后)。 以下是使用 Python 嵌入的代码示例: #include int main(int argc, char** argv) { Py_SetPythonHome
假设我有以下列表,对应于及时的股票价格: prices = [1, 3, 7, 10, 9, 8, 5, 3, 6, 8, 12, 9, 6, 10, 13, 8, 4, 11] 我想确定以下总体上最
所以我试图在选择某个单选按钮时更改此框架的背景。 我的框架位于一个类中,并且单选按钮的功能位于该类之外。 (这样我就可以在所有其他框架上调用它们。) 问题是每当我选择单选按钮时都会出现以下错误: co
我正在尝试将字符串与 python 中的正则表达式进行比较,如下所示, #!/usr/bin/env python3 import re str1 = "Expecting property name
考虑以下原型(prototype) Boost.Python 模块,该模块从单独的 C++ 头文件中引入类“D”。 /* file: a/b.cpp */ BOOST_PYTHON_MODULE(c)
如何编写一个程序来“识别函数调用的行号?” python 检查模块提供了定位行号的选项,但是, def di(): return inspect.currentframe().f_back.f_l
我已经使用 macports 安装了 Python 2.7,并且由于我的 $PATH 变量,这就是我输入 $ python 时得到的变量。然而,virtualenv 默认使用 Python 2.6,除
我只想问如何加快 python 上的 re.search 速度。 我有一个很长的字符串行,长度为 176861(即带有一些符号的字母数字字符),我使用此函数测试了该行以进行研究: def getExe
list1= [u'%app%%General%%Council%', u'%people%', u'%people%%Regional%%Council%%Mandate%', u'%ppp%%Ge
这个问题在这里已经有了答案: Is it Pythonic to use list comprehensions for just side effects? (7 个答案) 关闭 4 个月前。 告
我想用 Python 将两个列表组合成一个列表,方法如下: a = [1,1,1,2,2,2,3,3,3,3] b= ["Sun", "is", "bright", "June","and" ,"Ju
我正在运行带有最新 Boost 发行版 (1.55.0) 的 Mac OS X 10.8.4 (Darwin 12.4.0)。我正在按照说明 here构建包含在我的发行版中的教程 Boost-Pyth
学习 Python,我正在尝试制作一个没有任何第 3 方库的网络抓取工具,这样过程对我来说并没有简化,而且我知道我在做什么。我浏览了一些在线资源,但所有这些都让我对某些事情感到困惑。 html 看起来
我是一名优秀的程序员,十分优秀!