3
\$\begingroup\$

I am building what essentially could be viewed as a glorified database wrapper as a Python package, where I'm having several classes and functions spread out into different modules. My current problem is how to share the database connections with the different modules.

An example class in user.py:

class User(object):
    def __init__(self, user_name, db_con):
        self.user_name = user_name
        self._db_con = db_con

Which results in my __init__.py looking like this:

from .user import User as _User

def _connect_dbs():
    econ = _mdb.connect(host='db.com',
                        user='user', passwd=pass,
                        db='db', charset='utf8')
    return econ


_db = _connect_dbs()

def User(user_name):
    return _User(user_name, _db)

Is this a good solution, or could I implement it in another manner? While this avoids global variables, it does result in some code I would rather not have to write for quite a few functions.

\$\endgroup\$
2
\$\begingroup\$

If you are creating a database wrapper, why not make a lib out of the wrapper and stick it into a lib directory that other modules/classes can import? So, your Users class would be in a directory structure like this:

project/
    account.py
    lib/
        database.py
    user.py
    zombie.py

Your database.py would look something like:

import pymysql

class Database:    
    @staticmethod
    def connect_dbs():
        econ = _mdb.connect(host='db.com',
                            user='user', passwd=pass,
                            db='db', charset='utf8')
        return econ

Then, in the user.py, you'd simply do an import like:

from .lib.database import Database as MyDatabase

Then, to get the connection, something along the lines of:

my_connection = MyDatabase.connect_dbs()

EDIT: As an example, see this repl.it:

class Database:
    connection = None

    def __init__(self):
        print "Instantiating!"

    def connect_dbs(self):
        if self.connection is not None:
            return self.connection

        self.connection = 1
        return self.connection


class User:
    db = None

    def __init__(self):
        self.db = Database()

    def save_user(self):
        print self.db.connect_dbs()

U = User()
for i in range(30):
    U.save_user() # Only instantiates the connection once, then reuses it 30x
\$\endgroup\$
  • \$\begingroup\$ I like this solution, but wouldn't this create a new connection instance every time connect_dbs is called? My solution was based solely on trying to avoid this. \$\endgroup\$ – Jimmy C Oct 3 '14 at 19:27
  • \$\begingroup\$ Unfortunately, yes, it would create a new connection instance every time (unless you were to instantiate MyDatabase to a User property, then in class Database > connect_dbs, instead of returning econ, you would store that in self.econ or whatever). \$\endgroup\$ – jsanc623 Oct 3 '14 at 20:12
  • \$\begingroup\$ @JimmyC I've updated my answer to reflect my previous comment \$\endgroup\$ – jsanc623 Oct 3 '14 at 20:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.