【问题标题】:Using Eve's DB layer without HTTP在没有 HTTP 的情况下使用 Eve 的 DB 层
【发布时间】:2014-10-08 19:02:39
【问题描述】:

在我的应用程序中,MongoDB 集合需要由服务器端脚本作业更新(即:每 30 分钟从其他 API 抓取/拉取的 cron 作业)。我真正想做的是更新 MongoDB 集合,但要根据架构验证数据并包含元数据(更新、创建等)。

想到解决这个问题的两种方法是:

  1. 有一个假客户端来执行 HTTP POST/PUT/PATCHES。但是,这意味着这个假客户端必须处理诸如身份验证/授权/last-modified-since 之类的事情。
  2. 使用 PyMongo 直接与数据库交互。但是,这意味着我不会进行数据验证或存储元数据。

Eve 是否有数据库挂钩,以便我可以在不使用 HTTP 的情况下进行丰富的 Eve 数据库更新?

【问题讨论】:

    标签: eve


    【解决方案1】:

    我能够在一个单独的脚本中运行它,该脚本可以由 jenkins 定期运行。我正在导入的 run.py 中的应用程序是我在 eve quickstart 末尾拥有的应用程序。

    from run import app
    from eve.methods.post import post_internal
    
    payload = {
        "firstname": "Ray",
        "lastname": "LaMontagne",
        "role": ["contributor"]
    }
    
    with app.test_request_context():
        x = post_internal('people', payload)
        print(x)
    

    post_internal 运行eve.utils.parse_request,它依赖于flask.request,所以需要with app.test_request_context()app.app_context() 对于这种方法是不够的。

    如果您是烧瓶新手(像我一样),请阅读 appcontextreqcontext 的文档。

    【讨论】:

    • put_internal、patch_internal、deleteitem_internal 现已推出。
    【解决方案2】:

    从 v0.5 开始(目前在开发分支上,但您可以立即提取并使用它)您可以使用 post_internal 添加数据:

       Intended for internal post calls, this method is not rate limited,
       authentication is not checked and pre-request events are not raised.
       Adds one or more documents to a resource. Each document is validated
       against the domain schema. If validation passes the document is inserted
       and ID_FIELD, LAST_UPDATED and DATE_CREATED along with a link to the
       document are returned. If validation fails, a list of validation issues
       is returned.
    

    添加更多内部方法来涵盖现在可通过 HTTP 使用的所有 CRUD 操作可能是有意义的。不过,您仍然可以立即调用它们。

    更新:v0.5 已发布,_internal 方法可用于所有 CRUD 操作。

    【讨论】:

    • 太棒了!对于 put/patch/delete,我可能会遵循 post vs post_internal 模式。
    • 2 个后续问题:1) 对于从单独的 .py 脚本与 flask/eve 交互有什么建议吗? This answer 似乎可行,但不喜欢仅为内部任务创建 http 端点,然后放入逻辑以阻止其他人的想法。 2) 由于 get_document 中存在 etag/IF_MATCH 约束,以创建 post_internal 的方式创建 put_internal 是不够的。
    • On 2) 您可以尝试通过配置禁用 etag 匹配(即使是暂时的)。我计划研究它,看看我是否能想出新的“内部”编辑方法。 1)从未尝试过,但是如果您当然要访问网络服务器,它会起作用;或者你可以使用我猜的类似greenlet/celery的东西?不要认为烧瓶本身支持(虽然不是我的领域)。
    • 是的,我认为 1) 可能更像是一个边界烧瓶问题。至于 2),也许将 etag 比较实现为装饰器可以很容易地绕过 internal_put/delete/patch。
    【解决方案3】:

    如果您想在自定义端点中执行以下操作...

    1. 接受一些POSTed 数据
    2. 以某种方式处理数据
    3. 执行post_internal()
    4. 将结果作为响应返回

    ...你会这样做:

    from eve.methods.post import post_internal
    from eve.render import send_response
    
    def my_custom_endpoint(**kwargs):
    
        data = json.loads(request.data.decode())
    
        # <manipulate data here>    
    
        resp = post_internal('crew', data)
        return send_response('crew', resp)
    

    实际上,您最好使用 Eve 的Event Hooks 来做这种事情。但是如果有一些事件挂钩没有涵盖的情况,这种方法可能会很有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-05
      • 2016-05-01
      • 2012-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多