Reputation: 119
Problem Statement
I am building an API that must retrieve documents from a mongodb database, and I need to define a route in the Flask app that allows me to use the Flask URL variable as a value in my mdb query.
I have tried the following:
@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])
Expected results
I was expecting to be able to go to a route like http://127.0.0.1:5000/infrastructure/mine
and see all of the documents whose primary type in the database is mine
returned as JSON.
Actual results
I received a 500 Internal Server Error and the following error message:
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
Example data from Mongo, showing the way the properties are nested
Question
What do I need to do in order to get my query filter in a format that mongo will accept?
Upvotes: 0
Views: 1170
Reputation: 119
As mentioned by Alexandre Mahdhaoui in this answer, I needed to pass a dict
as my filter argument, but for some reason my database required dot notation for access. This answer contains the complete solution:
@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])
Upvotes: 1
Reputation: 841
I suggest you directly pass a dict
as your filter argument instead of jsonify(f'properties.type.primary: {infrastructure_type}')
Example:
@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])
Upvotes: 1