can i set up a mysql db connection as a class ?

N

nephish

hey there,
i have a huge app that connects to MySQL. There are three threads that
are continually connecting and disconnecting to the db. The problem is,
if there is an error, it faults out sometimes without closing the
connection. i connect like this.
db = MySQLdb.connect(host="localhost", user="MyUser",
passwd="MyPassword", db="Stuff")
cursor=db.cursor()

then i use the cursor.execute("SELECT yadda yadda

my question is, is there a way i can set up a global connection so that
when the program loads, it connects once, then stays connected ? maybe
i could assign instances of the cursor ?

please someone let me know if you have any good ideas

sk
 
B

*binarystar*

that's definitely the way to go ..

-create a database_object
-initialise at start up
-then pass the database object to other classes as needed ...

If you want to get really fancy have a look at some ORM's ... I think
there is a Python one called SQLObject?
 
N

nephish

This is great !

ok, i dont really have a lot of time to get into the ORMS (before your
post, this is the first i have heard of it) and my stuff is due on
Monday. he he.

but, if i am able to make a global db connection, and multiple cursors
pointing to the same connection object, how do i pull that off without
making new db connections?

something like
class db(self):
def __init__(self):
db = MySQLdb.connect(host="localhost", user="MyUser",
passwd="MyPassword",
db="Stuff")
def cursor(self):
cursor = db.cursor()
return cursor


then have in my threads that need to connect

cursor = db.cursor()
cursor2 = db.cursor()

and so on ? i may be way outta whack here. i am still new at classes,
methods, and modules.
i do have Essential Reference on the way from Amazon though ! :)

thanks again
 
B

*binarystar*

your on the right track ... create something like this ( hope the formatting doesn't go to hay wire )

class DB_Connector(object):

""" Humble Database Connection Class """

def __init__(self, host="localhost", user="MyUser",passwd="MyPassword", **other_db_arguments):

self.host = host
self.user = user
self.passwd = passwd

# Unpack Other Database Arguments Here


self.CreateConnection()

def CreateConnection( self ):

self.cursor = MySQLdb.connect(self.host, self.user, self.passwd)

def DestroyConnection( self ):

self.cursor.close()

def Execute( self, sql_statement ):

self.cursor.Execute( sql_statement )

return self.cursor.FetchAll()

Then when you run your program create an instance of the object

db_connection = DB_Connector( 'localhost', 'administrator', 'betelgeuse99', auto_commit=1, other_keyword_arg="yes" )

now when you pass the db_connection instance to other classes, a copy will be made automagically

thread_1_instance = ThreadingClass( db_connection )
thread_2_instance = ThreadingClass( db_connection )
thread_3_instance = ThreadingClass( db_connection )

should work ..

I hope this is useful
 
B

*binarystar*

Oops .. slight edit


now when you pass the db_connection instance to other classes, a reference will be passed automagically
 
W

Winfried Tilanus

On 04/28/2006 07:54 AM, *binarystar* wrote:

Just wondering: is there any risk of two threads accessing the Execute
function at the same time and getting something like this on the same
cursor object:

thread_1: self.cursor.Execute( sql_statement )
thread_2: self.cursor.Execute( sql_statement )
thread_1: return self.cursor.FetchAll()
thread_2: return self.cursor.FetchAll()

In that case the queries would seriously be messed up. My intuition says
this would need some locking or a 'cursor-pool'.

best wishes,

Winfried
 
B

*binarystar*

I suppose that is possible because you are calling the one instance of a cursor object ... maybe you have to create a copy of the cursor object, rather than passing a reference to the one object? or set up the db_connection objects inside each of the threads? ..
 
W

Winfried Tilanus

On 04/28/2006 08:35 AM, *binarystar* wrote:

Looking better at the """ Humble Database Connection Class """: if I am
not mistaken, it seems to mix up connections and cursors.

MySQLdb has a thread safety level of '1', meaning: "Threads may share
the module, but not connections". So you have to give each thread an own
connection. Beside of that I would prefer not to share the cursor
object, although it should not really matter.

The following should work and make the cursors private to the Execute
function (untested):

class DB_Connector(object):

""" Humble Database Connection Class """
def __init__(self, host="localhost",
user="MyUser",
passwd="MyPassword",
**other_db_arguments):
self.host = host
self.user = user
self.passwd = passwd
# Unpack Other Database Arguments Here
self.CreateConnection()

def CreateConnection(self):
self.connection = MySQLdb.connect(self.host,
self.user,
self.passwd)

def DestroyConnection(self):
self.connection.close()

def Execute(self, sql_statement):
cursor = self.connection.cursor()
cursor.execute(sql_statement)
result = cursor.fetchall()
cursor.close()
return result
 
N

nephish

So this opens and closes the connection every time i run the query?
thats cool. i think that would fit in well. so when i need to run the
query, i pass something like

query = "SELECT * FROM `Table` WHERE `foo` = 'bar'"

result = DB_Connector.Execute(query)

and the result would be the same as if i ran the query right there in
the thread?

thanks for all your help gents, this is helping me a lot.
 
D

Dennis Lee Bieber

So this opens and closes the connection every time i run the query?
thats cool. i think that would fit in well. so when i need to run the
query, i pass something like

query = "SELECT * FROM `Table` WHERE `foo` = 'bar'"

result = DB_Connector.Execute(query)
You should be creating a thread (if multiple threads) local
connection object first. That will create the connection at the start,
and keep it until you remove it. .Execute() is only creating a cursor
for the span of time needed to perform the query.

As a rudimentary example (snippets, not a full program, closer to
pseudo-code):

#various imports

#various defs, etc.

if __name__ == "__main__":
#create the connection at the top of the processing
#(this could also be the initialization part of a thread function
myCon = DB_Connector(host, user, passwd, other, args)
#use the same connection object for multiple queries
#this could be the main loop of a thread
while not Done:
query = something #formulate a query by whatever means
#create cursor in this connection, execute query, fetch all
#data, close/delete the cursor (but not the connection)
data = myCon.Execute(query)
#end of processing loop (thread exit logic)
#close/delete the connection
myCon.DestroyConnection()
and the result would be the same as if i ran the query right there in
the thread?

I think I'd modify the Execute() method a bit...

def Execute(self, sql_statement, parms= None):
cursor = self.connection.cursor()
if parms:
cursor.execute(sql_statement, parms)
else:
cursor.execute(sql_statement)
result = cursor.fetchall()
cursor.close()
return result

.... since the recommendation is that one should NOT attempt to put all
the data values into the query string itself, but use parameterized
queries and let the cursor.execute() do the proper formatting...

Instead of (and what's with the back quotes?)
query = "SELECT * FROM `Table` WHERE `foo` = 'bar'"
data = myCon.Execute(query)
use
query = "select * from Table where foo = %s"
data = myCon.Execute(query, ("bar",))
--
 
E

Ed Leafe

my question is, is there a way i can set up a global connection so
that
when the program loads, it connects once, then stays connected ? maybe
i could assign instances of the cursor ?

We do something like this in Dabo. We define connections, giving
each an identifying name, and the application object loads the
definitions at startup (without actually connecting). When a business
object needs a connection, they call
self.Application.getConnectionByName(connName). If that connection
hasn't been made, the app connects and returns a reference to the
connection. It also stores the reference, so that the next time a
business object requests that connection, it simply returns the
existing reference.

<shameless plug>
If you're developing database applications, especially if they
involve a GUI, you really should take a look at Dabo. It's an app
framework written by database developers for database developers.
</shameless plug>

-- Ed Leafe
-- http://leafe.com
-- http://dabodev.com
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,780
Messages
2,569,608
Members
45,253
Latest member
BlytheFant

Latest Threads

Top