Python - accessing single database wrapper object from multiple objects
<p>I have a simple Python wrapper around a MySQL database, and I need to be able to access it from inside other custom class objects within Python. The wrapper class lives in a separate file to each of the other custom classes. So far I've only been able to find the following ways of doing things:</p>

<ol>
<li>Make the database object global (bad)</li>
<li>Pass the database object into every other object's constructor (inelegant)</li>
<li>Stop using the database wrapper class entirely (annoying)</li>
</ol>

<p>There must surely be a better way of doing this in Python (yes, I have searched the web and Stack Overflow, but apparently I'm searching for the wrong keywords). Can anyone explain what it is? I only need one database connection, and most of my other classes need to use it. Dummy Python code explaining the sort of thing I'm trying to do follows.</p>

<p>(Partial) Database wrapper class:</p>

<pre><code>import mysql.connector

class Database:

    def __init__( self, username, password, database, host = 'localhost' ):
        self.connection = mysql.connector.connect( user = username, password = password, database = database, host = host )
        self.connection.set_autocommit( True )
        self.cursor = self.connection.cursor( dictionary = True )

    def __del__( self ):
        self.cursor.close()
        self.connection.close()

    def fetchAll( self, query, constraints = None ):
        self.cursor.execute( query, constraints )
        return self.cursor.fetchall()

    def delete( self, id, table, key = 'id' ):
        self.cursor.execute( 'DELETE FROM `' + table + '` WHERE `' + key + '` = %s', ( id, ) )
</code></pre>

<p>Another class requiring access to the database (N.B. undeclared object <code>db</code> in class methods):</p>

<pre><code>class Queue:
    def __init__( self ):
        self.jobs = []

    def refreshJobs( self ):
        self.jobs = db.fetchAll( 'SELECT * FROM `jobs`' )

    def deleteJob( self, id ):
        db.delete( id, 'jobs' )
        self.refreshJobs()
</code></pre>

<p>A third class that accesses the database (N.B. undeclared object <code>db</code> in class methods):</p>

<pre><code>class User:
    def __init__( self, email ):
        self.email = email
        details = db.fetchAll( 'SELECT * FROM `users` WHERE `email` = %s', [email] )
        if( len( details ) == 1 ):
            self.password = details[0]['password']
</code></pre>

<p>Any suggestions much appreciated, except framework recommendations. I'd really like to deepen my understanding of how best to handle this sort of situation in Python. Thanks in advance!</p>

<p>Answering my own question since no one responded, and this might be useful to other people in future. I was recommended to use a "half-way" global, by writing an intermediary module that looks something like this:</p>

<pre><code>from my_db_class import Database
db = Database( 'user', 'password', 'database' )
</code></pre>

<p>Then in <code>Queue</code> and <code>User</code> classes, do something like this:</p>

<pre><code>from my_db_instantiation import db
</code></pre>

<p>You can then access the same <code>db</code> database object in each of the classes that requires it. Note that only <code>my_db_intermediary</code> imports <code>my_db_class</code> directly. All other modules import <code>my_db_intermediary</code>. It might seem a bit convoluted but it allows you to keep your class implementations separate from the parameters required to instantiate them, in this case the database class and its associated credentials.</p>

python mysql database mysql-connector-python