- added autoincrement=True to Column; will disable schema generation
of SERIAL/AUTO_INCREMENT/identity seq for postgres/mysql/mssql if
explicitly set to False
+- connection pool tracks open cursors and raises an error if connection
+is returned to pool with cursors still opened. fixes issues with MySQL,
+others
0.2.8
- cleanup on connection methods + documentation. custom DBAPI
if self.__engine.echo:
self.__engine.log("ROLLBACK")
self.__engine.dialect.do_rollback(self.connection)
+ self.__connection.close_open_cursors()
self.__transaction = None
def _commit_impl(self):
if self.__engine.echo:
# and not just plain tuples ?
self.close()
return None
-
+
class RowProxy:
"""proxies a single cursor row for a parent ResultProxy."""
def __init__(self, parent, row):
"""proxies a DBAPI connection object and provides return-on-dereference support"""
def __init__(self, pool):
self._threadfairy = _ThreadFairy(self)
+ self.cursors = weakref.WeakKeyDictionary()
self.__pool = pool
self.__counter = 0
try:
def invalidate(self):
self._connection_record.invalidate()
self.connection = None
+ self.cursors = None
self._close()
def cursor(self, *args, **kwargs):
try:
raise "this connection is closed"
self.__counter +=1
return self
+ def close_open_cursors(self):
+ for c in list(self.cursors):
+ c.close()
def close(self):
self.__counter -=1
if self.__counter == 0:
def __del__(self):
self._close()
def _close(self):
+ if self.cursors is not None and len(self.cursors):
+ raise exceptions.InvalidRequestError("This connection still has %d open cursors" % len(self.cursors))
if self.connection is not None:
try:
self.connection.rollback()
class _CursorFairy(object):
def __init__(self, parent, cursor):
self.__parent = parent
+ self.__parent.cursors[self]=True
self.cursor = cursor
+ def close(self):
+ if self in self.__parent.cursors:
+ del self.__parent.cursors[self]
+ self.cursor.close()
def __getattr__(self, key):
return getattr(self.cursor, key)