Python-Eve:使用预请求事件挂钩在插入数据库

时间:2015-12-06 14:00:31

标签: python mongodb eve

我通过在我的eve-API上执行POST请求将新数据添加到我的数据库中。 由于需要从Python端添加一些数据,我认为我可以使用pre-request event hook添加这些数据。

那么有没有办法在将数据插入数据库之前使用预请求挂钩修改POST请求中包含的数据?我已经了解了如何实现这样的钩子,但是在插入数据库之前没有任何关于如何修改数据的线索。

3 个答案:

答案 0 :(得分:5)

您可能希望查看database hooks,特别是insert hooks

  

当POST请求命中API并且新项目即将存储在数据库中时,会触发这些通风口:

     每个资源端点

on_insert

     

on_insert_<resource_name>用于特定资源端点。

     

回调函数可以挂钩这些事件,以便随意添加新字段或编辑现有字段。

在下面的代码中:

def before_insert(resource_name, documents):
    if resource_name == 'myresource':
        for document in documents:
            document['field'] = 'value'

app = Eve()
app.on_insert += before_insert

app.run()

每当POST命中API时,都会调用before_insert函数。该函数为每个文档更新field1。由于在将有效负载发送到数据库之前调用此回调,因此更改将持久保存到数据库。

一个有趣的选择是:

def before_insert(resource_name, documents):
    for document in documents:
        document['field'] = 'value'

app = Eve()
app.on_insert_myresource += before_insert

app.run()

在回调中,我们不再测试端点名称了。这是因为我们将回调挂钩到on_insert_myresoure事件,因此只有在myresource端点上执行POST请求时才会调用该函数。更好地分离关注点,代码更简单,并且还提高了性能,因为回调不会受到所有 API插入的影响。旁注,最终你可以将多个回调挂钩到同一个事件(因此使用加法运算符+=)。

答案 1 :(得分:0)

就我而言,如果给定属性包含在数据中,我想复制文档。

我必须使用pre_POST事件挂钩来做到这一点。

def pre_notifications(request):
    data = json.loads(request.get_data())
    if 'payload' in data and 'condition' in data:
        notification = data['payload']
        documents = []
        users = app.data.pymongo().db.users.find()
        for user in users:
            copy_notification = copy(notification)
            copy_notification['user_email'] = user['user_email']
            documents.append(copy_notification)
        request._cached_data = json.dumps(documents).encode('utf-8')

首先,我尝试替换request.data,但是它不起作用。对代码进行一些搜索后,我找出了_cached_data属性。然后就可以了。

答案 2 :(得分:0)

仅是对@Gustavo的回答的补充(我不能在他的回答中留下评论)。您可以更新request._cached_json属性,而无需序列化数据。

以他的例子为例:

def pre_notifications(request):
    data = json.loads(request.get_data())
    if 'payload' in data and 'condition' in data:
        notification = data['payload']
        documents = []
        users = app.data.pymongo().db.users.find()
        for user in users:
            copy_notification = copy(notification)
            copy_notification['user_email'] = user['user_email']
            documents.append(copy_notification)
        request._cached_json = documents