如何使用 PyMongo 基于 Flask URL 变量检索 MongoDB 中的记录?

Posted

技术标签:

【中文标题】如何使用 PyMongo 基于 Flask URL 变量检索 MongoDB 中的记录?【英文标题】:How do I retrieve records in MongoDB with PyMongo based on Flask URL variables? 【发布时间】:2021-10-30 09:40:48 【问题描述】:

问题陈述

我正在构建一个 API,它必须从 mongodb 数据库中检索文档,并且我需要在 Flask 应用程序中定义一个路由,以允许我在我的 mdb 查询中使用 Flask URL 变量作为值。

我尝试了以下方法:

@app.route("/infrastructure/<infrastructure_type>")
def get_infrastructure(infrastructure_type):
    infrastructure = db.infrastructure.find(jsonify(f'properties.type.primary: infrastructure_type'), projection = "_id": False)
    return jsonify([resource for resource in infrastructure])

预期结果

我希望能够转到像 http://127.0.0.1:5000/infrastructure/mine 这样的路径,并查看数据库中主要类型为 mine 的所有文档以 JSON 形式返回。

实际结果

我收到 500 内部服务器错误和以下错误消息:

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.9/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/ben/Desktop/repos/rdcep/shotgun-api/app.py", line 23, in get_infrastructure
    infrastructure = db.infrastructure.find(jsonify(f'properties.type.primary: infrastructure_type'), projection = "_id": False)
  File "/usr/local/lib/python3.9/site-packages/pymongo/collection.py", line 1523, in find
    return Cursor(self, *args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/pymongo/cursor.py", line 144, in __init__
    validate_is_mapping("filter", spec)
  File "/usr/local/lib/python3.9/site-packages/pymongo/common.py", line 494, in validate_is_mapping
    raise TypeError("%s must be an instance of dict, bson.son.SON, or "
TypeError: filter must be an instance of dict, bson.son.SON, or any other type that inherits from collections.Mapping

来自 Mongo 的示例数据,显示属性的嵌套方式

问题

我需要做什么才能让我的查询过滤器采用 mongo 可以接受的格式?

【问题讨论】:

【参考方案1】:

我建议您直接传递 dict 作为过滤器参数,而不是 jsonify(f'properties.type.primary: infrastructure_type')

例子:

@app.route("/infrastructure/<infrastructure_type>")
def get_infrastructure(infrastructure_type):
    infrastructure = db.infrastructure.find('properties': 'type': 'primary': infrastructure_type, projection = "_id": False)
    return jsonify([resource for resource in infrastructure])

【讨论】:

这通过没有错误,但在客户端返回一个空数组。有什么想法吗? 有趣的是,您的过滤器在我看来是正确的,但当我使用它在 Atlas GUI 中进行过滤时也没有返回任何内容。在 Atlas 中,我可以使用点符号来获得预期的结果。 我想通了!它确实要求我按照您的指示传递一个 dict,但出于某种原因,它只想使用点符号:db.infrastructure.find('properties.type.primary': infrastructure_type, projection = "_id": False)【参考方案2】:

正如Alexandre Mahdhaoui 在this answer 中提到的,我需要传递一个dict 作为我的过滤器参数,但由于某种原因,我的数据库需要点符号才能访问。此答案包含完整的解决方案:

@app.route("/infrastructure/<infrastructure_type>")
def get_infrastructure(infrastructure_type):
    infrastructure = db.infrastructure.find('properties.type.primary': infrastructure_type, projection = "_id": False)
    return jsonify([resource for resource in infrastructure])

【讨论】:

以上是关于如何使用 PyMongo 基于 Flask URL 变量检索 MongoDB 中的记录?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 PyMongo 与 Flask 蓝图一起使用?

跨多个模块使用 Flask-pymongo

如何使用 flask_pymongo 将数据从 mongodb 显示到烧瓶模板?

使用 flask_pymongo 时身份验证失败

使用 PyMongo 和 Flask 进行分页

Flask 扩展 Flask-PyMongo