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 >>> |