I have a large Flask
project spread across multiple modules. I want all of those modules to get access to my MongoDB (PyMongo
) database connection. According to best practices, I want exactly one connection pool to persist throughout the application (i.e. throughout all modules).
Infeasible Solutions (from other related StackOverflow answers)
- I cannot create a global variable and pass that around to each module I call because that is not thread-safe (especially when my
db
object is not read-only). Example follows. - I cannot create a new connection for every request because that is inefficient.
- I cannot use the
Flask.g
"global" variable because it is wiped off with every request, making it essentially equivalent to point 2. - I cannot simply put the database connection code into a new module (like
config.py
) and call it when required from other modules because then I would be creating new connections every time I call it from the different modules.
Problem
- How do I create a single and persistent MongoDB connection in a thread- and process- safe manner?
- How do I give access to this across modules? In other words, how to make it global across modules?
- Is there no best-practice about this? The literature is either outdated or non-existent. Please answer for MongoDB (specifically PyMongo, if possible).
Example
This is a minimum working example of how I would create a global variable and use it across modules (Point 1 in Infeasible Solutions).
main.py
from module1 import helper_function
app = Flask(__name__)
db = new_db_connection()
@app.route('/page1'):
def page1():
db_return = db.query1()
db.cache = new_value # this makes this entire code thread-unsafe
return db_return
@app.route('/page2'):
def page2():
db_return = db.query2()
db_return2 = helper_function(db) # doesn't seem right that I have to pass this object around all the time
return db_return
module1.py
def helper_function(db):
db_return = db.query3()
return db_return