The correct way to create a database connection is available in many python modules

I want to make one database object available in many python modules.

For a related example, I create globl.py:

DOCS_ROOT="c:\docs" ## as an example SOLR_BASE="http://localhost:8636/solr/" 

Any other module that needs it can do

 from globl import DOCS_ROOT 

Now, in this case, I want to do the same with the database connection objects, share them in many modules .

 import MySQLdb conn = MySQLdb.connect (host="localhost"...) cursor = conn.cursor() 

I tried this on the interpreter:

 from globl import cursor 

and it seems to work. But I suspect that this will be because the same module will be executed every time it imports from it. So is that right?

+6
source share
3 answers

You suspect it is wrong. The code will be executed only once - subsequent imports simply refer to the module via sys.modules and do not restart it.

(Note that this is so if you always use the same path to import the module - if you execute from globl import cursor in one place and from my.fullyqualified.project.global import cursor in another, you will probably find code is executed.)

Edit to add , as S. Lott says in a comment, is a great way to handle a global object.

+3
source

Even if the import does not run the code several times, this is definitely not the right way.

Instead, you should hide the process of getting the connection or cursor behind the function. You can then implement this function using either the Singleton template or the Object Pool>.

So, it will be something like this:

db.py:

 _connection = None def get_connection(): global _connection if not _connection: _connection = MySQLdb.connect(host="localhost"...) return _connection # List of stuff accessible to importers of this module. Just in case __all__ = [ 'getConnection' ] ## Edit: actually you can still refer to db._connection ## if you know that the name of the variable. ## It just left out from enumeration if you inspect the module 

someothermodule.py:

 import db conn = db.get_connection() # This will always return the same object 

By the way, depending on what you are doing, there might not be much good idea to share your connection object, rather than creating a new one every time you need it.

But why do you want to write the get_connection() method to abstract from these problems in the rest of your code.

+25
source

I think Daniel already answered this question, although I would like to add some comments regarding the cursor object that you want to split.

Generally, it is not recommended to share the cursor object this way. Of course, this depends on your program, but as a general solution, I would recommend that you hide this cursor object behind the factory β€œcursors”. Basically, you can create a cursor() or get_cursor() method instead of making the cursor a global variable. The main advantage (but not the only one) - you can hide the more complex logic of this "factory" - pooling, automatic reconnection in case of connection failure, etc. Even if you do not need it right away - it will be very easy to add later if you start using this approach now, and for now you can keep this implementation as simple as return _cursor .

And yes, nevertheless, the module itself will be imported only once.

+1
source

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


All Articles