I found the following code on the net -
def count(self):
- db = sqlite.connect(self.filename,
isolation_level=ISOLATION_LEVEL)
- try:
- try:
- cur = db.cursor()
- cur.execute("select count(*) from sessions")
- return cur.fetchone()[0]
- finally:
- cur.close()
- finally:
- db.close()
I don't understand though why the second try is not after the line cur
= db.cursor(). Can anyone explain for me why?
/Barry.
Better question is why is there a try with no except...
Better yet, WHY is there two TRY statements when there could quite
happily be only one...
Towards what you are asking, I GUESS...because the author hoped to
handle the cases where cur failed to get assigned...but then
his .close method of it would likely not work anyway...I mean...does
this even work...YUCK
I shouldn't have written "Nested try...except" as the title, instead I
mean "Nested try...finally". Sorry about that...
Anyway, how would you do this? That is, use a finally to close the
network connection and the cursor?
Thanks for your help,
Barry
Here's what I would do. Is it OK?
def ExecuteWithNoFetching(self, queryString):
sqlServerConnection = adodbapi.connect (";".join (connectors))
try:
cursor = sqlServerConnection.cursor()
try:
cursor.execute(queryString)
raise Exception("Exception")
sqlServerConnection.commit()
finally:
cursor.close()
finally:
sqlServerConnection.close()
No.. Why do you have raise statement?
"sqlServerConnection.commit()" never gets executed.
-N
It's demonstration code.
> -N
Because the author doesn't want to handle the exception here, only
make sure resources are freed.
> Better yet, WHY is there two TRY statements when there could quite
> happily be only one...
>
> Towards what you are asking, I GUESS...because the author hoped to
> handle the cases where cur failed to get assigned...but then
> his .close method of it would likely not work anyway...I mean...does
> this even work...YUCK
Indeed.
slightly OT : where this 'connectors' comes from ?
> try:
> cursor = sqlServerConnection.cursor()
> try:
> cursor.execute(queryString)
> raise Exception("Exception")
> sqlServerConnection.commit()
> finally:
> cursor.close()
> finally:
> sqlServerConnection.close()
Else it looks ok, even if a bit paranoïd. Also, opening a db
connection for each and every single query might not be the best
solution... And finally (no pun intented), this won't let you chain
calls within a single transaction.
Another, a bit more flexible solution could be something like:
def run_in_transaction(*funcs):
sqlServerConnection = adodbapi.connect (";".join (connectors))
try:
cursor = sqlServerConnection.cursor()
try:
for func in funcs:
func(cursor)
except Exception, e:
sqlServerConnection.rollback()
raise
else:
sqlServerConnection.commit()
finally:
cursor.close()
finally:
sqlServerConnection.close()
def do_something(cursor):
cursor.execute("some update query")
def do_something_else(cursor):
cursor.execute("some select query")
for row in cursor.fetchall():
if some_condition(row):
cursor.execute("some update query")
run_in_transaction(do_something, do_something_else)
And also, there's this new 'with' statement...
My 2 cents...
It's a pretty common mistake to make, I assume because there's a
tendency to line up the init and finalize statements. In other words,
it looks wrong for open and close to be in different columns:
open()
try:
do_stuff()
finally:
close()
It's almost always wrong for initiazation to be inside of the try
block.
Perhaps the advent of with blocks will help reduce this error in the
future.
Carl Banks
> Perhaps the advent of with blocks will help reduce this error in the
> future.
Indeed, and to encourage its use I think this thread ought to include the
'with statement' form of the function:
from __future__ import with_statement
from contextlib import closing
def count(self):
with closing(sqlite.connect(
self.filename,isolation_level=ISOLATION_LEVEL)) as db:
with closing(db.cursor()) as cur:
cur.execute("select count(*) from sessions")
return cur.fetchone()[0]