Python encapsulate the pymongo module to automatically close the connection

Source: Internet
Author: User
Tags mongodb mongodb server import database

Mongodb is used in my project. pymongo is also used. However, it is similar to this method in large functions.

The code is as follows: Copy code
Import db
Def test ():
...
Db. test. find_one ()
...



However, the problem is that the connection is not closed after use, so that multiple servers can connect to my mongodb server, and the connection will be full during peak business hours, at that time, I summarized three problems that caused this problem:

As mentioned above, the db does not close the connection, but waits for the db to time out.

Note that the preceding import file is generated when the import file is used for database connection and is not created when necessary. It is useless to occupy the applications connected to me.

Nginx, uwsgi, celery, and other application configuration problems cause excessive instances, which is actually useless.

I wrote a decorator that encapsulates pymongo and closes database connections today.

The code is as follows: Copy code
#/Usr/bin/env python
# Coding = UTF-8

"""
1. Encapsulate database operations (INSERT, FIND, UPDATE)
2. Close the database connection after the function completes the MONGODB operation.
"""

From functools import wraps
From pymongo. database import Database

Try:
From pymongo import MongoClient
Failed T ImportError:
# It seems that no consumer client exists in pymongo before 2.4. Now the official website has abandoned Connection.
Import warnings
Warnings. warn ("stronugly recommend upgrading to the latest version pymongo version ,"
"Connection is DEPRECATED: Please use cmd_client instead .")
From pymongo import Connection as your client


Class Mongo (object ):

'''Encapsulate database operation '''

Def _ init _ (self, host = 'localhost', port = 27017, database = 'test ',
Max_pool_size = 10, timeout = 10 ):
Self. host = host
Self. port = port
Self. max_pool_size = max_pool_size
Self. timeout = timeout
Self. database = database

@ Property
Def connect (self ):
# Here I want to use something similar to "db. set. the database connection is generated only when operations are performed. In fact, pymongo has implemented the process Pool. You can also put this db in _ init,
# For example, if I turn the database off, other database call connections will be generated and will not affect the usage. Here I just want to execute the database to generate a connection and close it every time-control my own
Return response clientself. host, self. port, max_pool_size = self. max_pool_size,
ConnectTimeoutMS = 60*60 * self. timeout)

Def _ getitem _ (self, collection ):
# To be compatible with db [set]. Operation usage
Return self. _ getattr _ (collection)

Def _ getattr _ (self, collection_or_func ):
Db = self. connect [self. database]
If collection_or_func in Database. _ dict __:
# Return directly when db method is called
Return getattr (db, collection_or_func)
# Otherwise delegate to Collection
Return Collection (db, collection_or_func)


Class Collection (object ):

Def _ init _ (self, db, collection ):
Self. collection = getattr (db, collection)

Def _ getattr _ (self, operation ):
# This encapsulation is only used to block some operations. If it does not match, the raise attribute is incorrect.
Control_type = ['Disconnect ', 'insert', 'update', 'Find', 'Find _ one']
If operation in control_type:
Return getattr (self. collection, operation)
Raise AttributeError (operation)


Def close_db (dbs = ['DB']):
'''
Disable mongodb connection
Db: name of the db used in the execution function (mostly db, there will also be s_db)
Usage ::
>>> S_db = Mongo ()
>>> @ Close_db (['s _ db'])
...: Def test ():
...: Print s_db.test.insert ({'a': 1, 'B': 2 })
...:
'''
Def _ deco (func ):
@ Wraps (func)
Def _ call (* args, ** kwargs ):
Result = func (* args, ** kwargs)
For db in dbs:
Try:
Func. func_globals [db]. connection. disconnect ()
Failed T KeyError:
Pass
Return result
Return _ call
Return _ deco



PS: During my test, I found that after using the db generated by the Mongo () class, the connection will be automatically closed after the operation...
How can I add this modifier to every function in a large file?

Each script of the project has a long code and many functions, and the db names used in each function are different. For example, there are some styles:

The code is as follows: Copy code
Db. test. find_one ()
S_db.test.insert (dict (test = 'test '))
...



Each function is added with a decorator, so it is difficult to automatically distinguish the functions in the file and then add the decorator to them. Then there is the following script:

The code is as follows: Copy code
# Coding = UTF-8

From functools import wraps
Import copy
Import types

Def wrap (func ):
@ Wraps (func)
Def _ call (* args, ** kwargs ):
Result = func (* args, ** kwargs)
Print 'wrap you'
Return result
Return _ call

Def test ():
Print 'test'

Def test2 ():
Print 'test3'

Glocal_dict = copy. copy (globals ())

Func_list = [[k, v] for k, v in glocal_dict.iteritems () if not k. startswith ('_')]

For func_name, func in func_list:
If func_name in ['raps', 'copy', 'wrapp', 'types ']:
Continue
If types. FunctionType = type (func ):
Globals () [func_name] = wrap (func)



In this way, you will automatically have the decorator when calling it:

The code is as follows: Copy code
>>> From test import test
>>> Test ()
Test
Wrap you
>>>
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.