Connection with mongodb in a verified way

I plan to write webapp in python using Flask and MongoDB (and probably Ming as ODM). The problem is that I would like my model and controller to be really well separated, one of the reasons for this was to be able to run simple unittests on separate components.

Now here is my problem, at some point in the request life cycle, I need to connect to MongoDB. Each request will have a separate connection. Flask offers a local thread object that can contain any variables that are global for the request, this seems to be a good place to establish a mongo connection. However, this creates a tough relationship between the data layer and the flask, which will make testing or managing them separately quite difficult.

So my question is whether there is an elegant solution for this. I myself came up with a couple of options, but they are very far from elegance.

At first, I could just provide the data module with a function that would tell her where to get the connection object from. Or, in a similar way, give it a function that it can use to retrieve a new connection.

The second option is to create a class that the module can use to connect to MongoDB, and then create 2 versions of this class, which uses the global Flask object, and the other simply connects to MongoDB.

Both of them do not seem really reliable or elegant for me, is there any way to do this better?

+4
source share
1 answer

One approach might be to use a single-level Python module level template. Create a module having a conn object (using a simple PyMongo)

try: conn = Connection(max_pool_size=20) except ConnectionFailure: app.logger.critical("Unable to connect to MongoDB") 

and then just create a wrapper for the PyMongo collection

 class Model(object): def __init__(self, table, db = app.config['DB_NAME']): self._table = table self._db = db def find_one(self, spec_or_id=None, *args, **kwargs): result = None try: result = conn[self._db][self._table].find_one(spec_or_id, *args, **kwargs) except InvalidName: app.logger.critical('invalid DB or Table name') finally: conn.end_request() return result 

Here conn.end_request() will result in a connection to return to the pool, and on each find_one () it will receive a connection from the pool. Do not worry, they are safe in flow.

now you can use the model somehow like

 result = Model(COLLECTION).find_one({user:'joe'}) 
+5
source

Source: https://habr.com/ru/post/1386812/


All Articles