The function code:
# Connect to the DB
try:
dbi = MySQLdb.connect(host='localhost', \
user='user', \
passwd='pass', \
db='dbname', \
port=3309)
print "Connected to DB ..."
except MySQLdb.Error, e:
apiErr = 2
apiErrMsg = "Error %d: %s" % (e.args[0], e.args[1])
return
# To prevent try..finally bug in python2.4,
# one has to nest the "try: except:" part.
try:
try:
sql = dbi.cursor()
sql.execute("""
SELECT *
FROM table
WHERE idClient = %s
""", (key, ))
access = sql.fetchall()
# [some more code here]
except MySQLdb.Error, e:
apiErr = 2
apiErrMsg = "Error %d: %s" % (e.args[0], e.args[1])
return
finally:
sql.close()
dbi.close()
I understand that in a try .. except .. finally, the finally block will always execute.
In the above code, I don’t want the finally in the second try block to execute if there is an exception in the first try block. What am I doing wrong?
(Note: Using python 2.4)
Clarification: I am not aware if MySQLdb closes connections automatically when an error occurs. The problem I am facing with the above code is, when there is an error in establishing a connection (the first try block of the code), calling dbi.close() in the finally block raises “AttributeError: ‘NoneType’ object has no attribute ‘close'” with reference to dbi …
Solution:
This worked as desired –
# define at the start
dbi = None
sql = None
In the finally block,
if sql is not None:
sql.close()
if dbi is not None:
dbi.close()
Thanks to those who replied. I learned something new from all of you. (I’ll try to phrase my questions more clearly the next time :).
I think in this case you do want to use finally, because you want to close those connections.
I disagree with the notion that you should have two try blocks in the same method.
I think the flaw in the design is acquiring the connection and performing the query in the same method. I would recommend separating the two. A service class or method knows about the unit of work. It should acquire the connection, pass it to another class that performs the query, and closes the connection when it’s done. That way the query method can throw any exception it encounters and leave the cleanup to the class or method that’s responsible for the connection.