3

I have Flask app with a Post model which spans across multiple MongoDB databases (db1, db2, db3,...), so I need to be able to query different dbs.
I'm using Flask-MongoEngine extension.

My __init__.py contains the following line:
db = MongoEngine(app)
and in config.py I have:
MONGODB_SETTINGS = {'DB': 'db1'}

I tried the following without success:

  1. Alter the connection parameter in the db object like this:
    db.connection = mongoengine.connect('db2')
    It didn't change anything. Executing post = Post.objects.all() still ran on the original db (db1).
  2. Create alias in the Post class meta like this:
    'db_alias': 'db1'
    Then I altered the connection parameter in the db object like this:
    db.connection = mongoengine.connect('db2', alias='db1')
    This would indeed create a connection to db2, but I couldn't change it to another db.
  3. Set MONGODB_SETTINGS to {'DB': 'db2'} and then db = MongoEngine(app)
    This doesn't work as well

It seems like once the model in models.py has been loaded (or connected to a db), you cannot change its connection.
Is that correct?
How can I change databases on the same model?
EDIT: The Django equivalent is the using parameter in the ORM which allows querying different DBs for the same model.

user1102018
  • 4,369
  • 6
  • 26
  • 33

1 Answers1

2

As you correctly identified, a MongoEngine instance and consequently all the documents (models) created from it are bound to a particular database.

You can (temporarily) change the database used by a document instance to an alias defined in the document's class by calling the switch_db method on the instance:

Post.objects.all().switch('db1').save()

would save all documents in the database db1 if db1 was defined as db_alias in the Post class (otherwise you'll get a ConnectionError).

Alternatively there are a number of ways to make the initial configuration "dynamic" and e.g. respect environment variables:

import os
app['MONGODB_SETTINGS'] = {'db': os.environ.get('DBNAME', 'db2')}

However, from your comment

Our system uses a number of databases to host this model

it seems that what you probably want is Sharding, where MongoDB takes care of distributing a collection over multiple mongod instances on multiple machines. In that case you connect to a mongos instead, which takes care of routing a query to the right shard. The database name is the same on each shard.

kynan
  • 13,235
  • 6
  • 79
  • 81