views:

40

answers:

3

Using the code below leaves me with an open connection, how do I close?

import pyodbc
conn = pyodbc.connect('DRIVER=MySQL ODBC 5.1 driver;SERVER=localhost;DATABASE=spt;UID=who;PWD=testest') 

csr = conn.cursor()  
csr.close()
del csr
+2  A: 

Connections have a close method. See PEP-249 (Python Database API Specification v2.0):

import pyodbc
conn = pyodbc.connect('DRIVER=MySQL ODBC 5.1 driver;SERVER=localhost;DATABASE=spt;UID=who;PWD=testest') 

csr = conn.cursor()  
csr.close()
del csr
conn.close()     #<--- Close the connection
unutbu
+1  A: 

You might try turning off pooling, which is enabled by default. See this discussion for more information.

import pyodbc
pyodbc.pooling = False
conn = pyodbc.connect('DRIVER=MySQL ODBC 5.1 driver;SERVER=localhost;DATABASE=spt;UID=who;PWD=testest') 

csr = conn.cursor()  
csr.close()
del csr
Matthew Rankin
Funny I could use the pooling, but mysql just starts another conn with a new ID.
+2  A: 

You can wrap the whole connection in a context manager, like the following:

import contextlib
import pyodbc
import sys

@contextmanager
def open_db_connection(connection_string, commit=False):
    connection = pyodbc.connect(connection_string)
    cursor = connection.cursor()
    try:
        yield cursor
    except pyodbc.DatabaseError as err:
        error, = err.args
        sys.stderr.write(error.message)
        cursor.execute("ROLLBACK")
        raise err
    else:
        if commit:
            cursor.execute("COMMIT")
        else:
            cursor.execute("ROLLBACK")
    finally:
        connection.close()

Then do something like this where ever you need a database connection:

with open_db_connection("...") as cursor:
    # Your code here

The connection will close when you leave the with block. This will also rollback the transaction if an exception occurs or if you didn't open the block using with open_db_connection("...", commit=True).

AndrewF
good idea, But I use Mysql and Sqlite....not oracle (well not directly:-)!) Where the connection string to driver... why import sys?
Whoops, I thought I replaced my oracle specific code with pyodbc, but I overlooked one (fixed now). The syntax is the same, since both use the common PEP 249 database API. I imported sys so I could write any exceptions to standard error. You could also use logging or just a plain print statement. And you pass the same connection string you were using before to open_db_connection().
AndrewF
Ok, looking at the code: What Do i get by doing? Seems like a lot of extra lines of code to check if connection is open?