I'm attempting to create a REST API that selects the appropriate mongo database to write to along with the correct collection. How do I have eve select the database with the same name as a parameter as well as the collection?
-
What do you have so far? Where are the database details stored? – Simeon Visser Jun 09 '15 at 22:43
-
I have the app working for one database but I want to have it in multiple. I have all of the settings in the settings.py file. For example, I'll want two databases, address and employee. Each of them will have one or more collections. I'd ideally be able to have a URL of the form localhost/employee/hr and have it access the hr collection in the employee database without touching anything address related. Does that makes sense? – Garrett M Jun 09 '15 at 22:50
-
@SimeonVisser Is that clear? – Garrett M Jun 10 '15 at 00:17
2 Answers
With upcoming v0.6 Eve will natively support multiple Mongo instances.
New: Support for multiple MongoDB databases and/or servers.
You can have individual API endpoints served by different Mongo instances:
mongo_prefix
resource setting allows overriding of the default MONGO prefix used when retrieving MongoDB settings from configuration. For example, set a resource mongo_prefix to MONGO2 to read/write from the database configured with that prefix in your settings file (MONGO2_HOST, MONGO2_DBNAME, etc.)
And/or you can use a different Mongo instance depending on the user hitting the database:
set_mongo_prefix()
andget_mongo_prefix()
have been added to BasicAuth class and derivates. These can be used to arbitrarily set the target database depending on the token/client performing the request.
A (very) naive implementation of user instances, taken from the docs:
from eve.auth import BasicAuth
class MyBasicAuth(BasicAuth):
def check_auth(self, username, password, allowed_roles, resource, method):
if username == 'user1':
self.set_mongo_prefix('MONGO1')
elif username == 'user2':
self.set_mongo_prefix('MONGO2')
else:
# serve all other users from the default db.
self.set_mongo_prefix(None)
return username is not None and password == 'secret'
app = Eve(auth=MyBasicAuth)
app.run()
Also:
Database connections are cached in order to not to loose performance. Also, this change only affects the MongoDB engine, so extensions currently targeting other databases should not need updates (they will not inherit this feature however.)
Hope this will cover your needs. It's currently on the development
branch so you can already experiment/play with it.

- 6,606
- 1
- 20
- 33
-
This is exactly what I needed. Is there a way to do it outside of auth? I want to change databases based on path or values in the request which I see as functionally different from auth. Also, would I be able to check if that value is the same as a database name instead? – Garrett M Jun 16 '15 at 14:38
Say you have parameters "dbname" and "collectionname", and a global MongoClient instance named "client":
collection = client[dbname][collectionname]
PyMongo's client supports the "[]" syntax for getting a database with a given name, and PyMongo's database supports "[]" for getting a collection.
Here's a more complete example with Flask:
client = MongoClient()
@app.route('/<dbname>/<collection_name>')
def find_something(dbname, collection_name):
return client[dbname][collection_name].find_one()
The good thing about my example is it reuses one MongoClient throughout, so you get optimal performance and connection pooling. The bad thing, of course, is you allow your users to access any database and any collection, so you'd want to secure that somehow.

- 23,641
- 4
- 57
- 70
-
Is there a way to do that for each call? Where on the stack would I put this kind of call to make sure that the correct database is used for CRUD operations? – Garrett M Jun 10 '15 at 16:07
-
Do you know if there is a way to easily use that kind of feature in a framework like eve or do I have to use just flask? – Garrett M Jun 11 '15 at 15:57