summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/engine
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2013-04-21 17:18:49 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2013-04-21 17:18:49 -0400
commit3aff498e4a96eda06f09f09f98e73e135719b388 (patch)
treef1ca2029cfd147478447d3cb98bae587a8ccb3c2 /lib/sqlalchemy/engine
parent1f6528ed8581ba63721bdc2a0593a5d39b9c27e0 (diff)
parentfbcdba12f88d88c509fc34eb8aab3f501d1b705b (diff)
downloadsqlalchemy-3aff498e4a96eda06f09f09f98e73e135719b388.tar.gz
merge into cymysql branch...
Diffstat (limited to 'lib/sqlalchemy/engine')
-rw-r--r--lib/sqlalchemy/engine/base.py120
-rw-r--r--lib/sqlalchemy/engine/ddl.py22
-rw-r--r--lib/sqlalchemy/engine/default.py8
-rw-r--r--lib/sqlalchemy/engine/result.py8
4 files changed, 73 insertions, 85 deletions
diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py
index 6242f0816..b4c9b1e1c 100644
--- a/lib/sqlalchemy/engine/base.py
+++ b/lib/sqlalchemy/engine/base.py
@@ -62,6 +62,7 @@ class Connection(Connectable):
self.__savepoint_seq = 0
self.__branch = _branch
self.__invalid = False
+ self.__can_reconnect = True
if _dispatch:
self.dispatch = _dispatch
elif engine._has_events:
@@ -213,8 +214,8 @@ class Connection(Connectable):
def closed(self):
"""Return True if this connection is closed."""
- return not self.__invalid and '_Connection__connection' \
- not in self.__dict__
+ return '_Connection__connection' not in self.__dict__ \
+ and not self.__can_reconnect
@property
def invalidated(self):
@@ -232,7 +233,7 @@ class Connection(Connectable):
return self._revalidate_connection()
def _revalidate_connection(self):
- if self.__invalid:
+ if self.__can_reconnect and self.__invalid:
if self.__transaction is not None:
raise exc.InvalidRequestError(
"Can't reconnect until invalid "
@@ -461,7 +462,6 @@ class Connection(Connectable):
self.engine.dialect.do_begin(self.connection)
except Exception, e:
self._handle_dbapi_exception(e, None, None, None, None)
- raise
def _rollback_impl(self):
if self._has_events:
@@ -475,7 +475,6 @@ class Connection(Connectable):
self.__transaction = None
except Exception, e:
self._handle_dbapi_exception(e, None, None, None, None)
- raise
else:
self.__transaction = None
@@ -490,7 +489,6 @@ class Connection(Connectable):
self.__transaction = None
except Exception, e:
self._handle_dbapi_exception(e, None, None, None, None)
- raise
def _savepoint_impl(self, name=None):
if self._has_events:
@@ -577,15 +575,15 @@ class Connection(Connectable):
and will allow no further operations.
"""
-
try:
conn = self.__connection
except AttributeError:
- return
- if not self.__branch:
- conn.close()
- self.__invalid = False
- del self.__connection
+ pass
+ else:
+ if not self.__branch:
+ conn.close()
+ del self.__connection
+ self.__can_reconnect = False
self.__transaction = None
def scalar(self, object, *multiparams, **params):
@@ -692,7 +690,6 @@ class Connection(Connectable):
dialect, self, conn)
except Exception, e:
self._handle_dbapi_exception(e, None, None, None, None)
- raise
ret = ctx._exec_default(default, None)
if self.should_close_with_result:
@@ -829,7 +826,6 @@ class Connection(Connectable):
self._handle_dbapi_exception(e,
str(statement), parameters,
None, None)
- raise
if context.compiled:
context.pre_exec()
@@ -876,7 +872,6 @@ class Connection(Connectable):
parameters,
cursor,
context)
- raise
if self._has_events:
self.dispatch.after_cursor_execute(self, cursor,
@@ -951,7 +946,6 @@ class Connection(Connectable):
parameters,
cursor,
None)
- raise
def _safe_close_cursor(self, cursor):
"""Close the given cursor, catching exceptions
@@ -972,23 +966,31 @@ class Connection(Connectable):
if isinstance(e, (SystemExit, KeyboardInterrupt)):
raise
+ _reentrant_error = False
+ _is_disconnect = False
+
def _handle_dbapi_exception(self,
e,
statement,
parameters,
cursor,
context):
- if getattr(self, '_reentrant_error', False):
- # Py3K
- #raise exc.DBAPIError.instance(statement, parameters, e,
- # self.dialect.dbapi.Error) from e
- # Py2K
- raise exc.DBAPIError.instance(statement,
+
+ exc_info = sys.exc_info()
+
+ if not self._is_disconnect:
+ self._is_disconnect = isinstance(e, self.dialect.dbapi.Error) and \
+ not self.closed and \
+ self.dialect.is_disconnect(e, self.__connection, cursor)
+
+ if self._reentrant_error:
+ util.raise_from_cause(
+ exc.DBAPIError.instance(statement,
parameters,
e,
- self.dialect.dbapi.Error), \
- None, sys.exc_info()[2]
- # end Py2K
+ self.dialect.dbapi.Error),
+ exc_info
+ )
self._reentrant_error = True
try:
# non-DBAPI error - if we already got a context,
@@ -1006,45 +1008,35 @@ class Connection(Connectable):
e)
context.handle_dbapi_exception(e)
- is_disconnect = isinstance(e, self.dialect.dbapi.Error) and \
- self.dialect.is_disconnect(e, self.__connection, cursor)
-
- if is_disconnect:
- dbapi_conn_wrapper = self.connection
- self.invalidate(e)
- if not hasattr(dbapi_conn_wrapper, '_pool') or \
- dbapi_conn_wrapper._pool is self.engine.pool:
- self.engine.dispose()
- else:
+ if not self._is_disconnect:
if cursor:
self._safe_close_cursor(cursor)
self._autorollback()
- if self.should_close_with_result:
- self.close()
-
- if not should_wrap:
- return
-
- # Py3K
- #raise exc.DBAPIError.instance(
- # statement,
- # parameters,
- # e,
- # self.dialect.dbapi.Error,
- # connection_invalidated=is_disconnect) \
- # from e
- # Py2K
- raise exc.DBAPIError.instance(
- statement,
- parameters,
- e,
- self.dialect.dbapi.Error,
- connection_invalidated=is_disconnect), \
- None, sys.exc_info()[2]
- # end Py2K
+
+ if should_wrap:
+ util.raise_from_cause(
+ exc.DBAPIError.instance(
+ statement,
+ parameters,
+ e,
+ self.dialect.dbapi.Error,
+ connection_invalidated=self._is_disconnect),
+ exc_info
+ )
+
+ util.reraise(*exc_info)
finally:
del self._reentrant_error
+ if self._is_disconnect:
+ del self._is_disconnect
+ dbapi_conn_wrapper = self.connection
+ self.invalidate(e)
+ if not hasattr(dbapi_conn_wrapper, '_pool') or \
+ dbapi_conn_wrapper._pool is self.engine.pool:
+ self.engine.dispose()
+ if self.should_close_with_result:
+ self.close()
# poor man's multimethod/generic function thingy
executors = {
@@ -1107,8 +1099,8 @@ class Connection(Connectable):
trans.commit()
return ret
except:
- trans.rollback()
- raise
+ with util.safe_reraise():
+ trans.rollback()
def run_callable(self, callable_, *args, **kwargs):
"""Given a callable object or function, execute it, passing
@@ -1214,8 +1206,8 @@ class Transaction(object):
try:
self.commit()
except:
- self.rollback()
- raise
+ with util.safe_reraise():
+ self.rollback()
else:
self.rollback()
@@ -1540,8 +1532,8 @@ class Engine(Connectable, log.Identified):
try:
trans = conn.begin()
except:
- conn.close()
- raise
+ with util.safe_reraise():
+ conn.close()
return Engine._trans_ctx(conn, trans, close_with_result)
def transaction(self, callable_, *args, **kwargs):
diff --git a/lib/sqlalchemy/engine/ddl.py b/lib/sqlalchemy/engine/ddl.py
index 53d7f3340..c61a9d59c 100644
--- a/lib/sqlalchemy/engine/ddl.py
+++ b/lib/sqlalchemy/engine/ddl.py
@@ -21,7 +21,7 @@ class SchemaGenerator(DDLBase):
tables=None, **kwargs):
super(SchemaGenerator, self).__init__(connection, **kwargs)
self.checkfirst = checkfirst
- self.tables = tables and set(tables) or None
+ self.tables = tables
self.preparer = dialect.identifier_preparer
self.dialect = dialect
self.memo = {}
@@ -39,17 +39,17 @@ class SchemaGenerator(DDLBase):
(
(not self.dialect.sequences_optional or
not sequence.optional) and
- (
- not self.checkfirst or
- not self.dialect.has_sequence(
- self.connection,
- sequence.name,
- schema=sequence.schema)
- )
+ (
+ not self.checkfirst or
+ not self.dialect.has_sequence(
+ self.connection,
+ sequence.name,
+ schema=sequence.schema)
+ )
)
def visit_metadata(self, metadata):
- if self.tables:
+ if self.tables is not None:
tables = self.tables
else:
tables = metadata.tables.values()
@@ -117,7 +117,7 @@ class SchemaDropper(DDLBase):
self.memo = {}
def visit_metadata(self, metadata):
- if self.tables:
+ if self.tables is not None:
tables = self.tables
else:
tables = metadata.tables.values()
@@ -160,7 +160,7 @@ class SchemaDropper(DDLBase):
((not self.dialect.sequences_optional or
not sequence.optional) and
(not self.checkfirst or
- self.dialect.has_sequence(
+ self.dialect.has_sequence(
self.connection,
sequence.name,
schema=sequence.schema))
diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py
index 1db0f2ce4..daa9fe085 100644
--- a/lib/sqlalchemy/engine/default.py
+++ b/lib/sqlalchemy/engine/default.py
@@ -34,6 +34,10 @@ class DefaultDialect(interfaces.Dialect):
preparer = compiler.IdentifierPreparer
supports_alter = True
+ # the first value we'd get for an autoincrement
+ # column.
+ default_sequence_base = 1
+
# most DBAPIs happy with this for execute().
# not cx_oracle.
execute_sequence_format = tuple
@@ -679,7 +683,7 @@ class DefaultExecutionContext(interfaces.ExecutionContext):
lastrowid = proc(lastrowid)
self.inserted_primary_key = [
- c is autoinc_col and lastrowid or v
+ lastrowid if c is autoinc_col else v
for c, v in zip(
table.primary_key,
self.inserted_primary_key)
@@ -733,7 +737,6 @@ class DefaultExecutionContext(interfaces.ExecutionContext):
except Exception, e:
self.root_connection._handle_dbapi_exception(
e, None, None, None, self)
- raise
else:
inputsizes = {}
for key in self.compiled.bind_names.values():
@@ -752,7 +755,6 @@ class DefaultExecutionContext(interfaces.ExecutionContext):
except Exception, e:
self.root_connection._handle_dbapi_exception(
e, None, None, None, self)
- raise
def _exec_default(self, default, type_):
if default.is_sequence:
diff --git a/lib/sqlalchemy/engine/result.py b/lib/sqlalchemy/engine/result.py
index 7572564bb..88930081e 100644
--- a/lib/sqlalchemy/engine/result.py
+++ b/lib/sqlalchemy/engine/result.py
@@ -301,7 +301,7 @@ class ResultMetaData(object):
# this check isn't currently available if the row
# was unpickled.
if result is not None and \
- result[1] is not None:
+ result[1] is not None:
for obj in result[1]:
if key._compare_name_for_result(obj):
break
@@ -443,7 +443,6 @@ class ResultProxy(object):
except Exception, e:
self.connection._handle_dbapi_exception(
e, None, None, self.cursor, self.context)
- raise
@property
def lastrowid(self):
@@ -467,7 +466,6 @@ class ResultProxy(object):
self.connection._handle_dbapi_exception(
e, None, None,
self._saved_cursor, self.context)
- raise
@property
def returns_rows(self):
@@ -752,7 +750,6 @@ class ResultProxy(object):
self.connection._handle_dbapi_exception(
e, None, None,
self.cursor, self.context)
- raise
def fetchmany(self, size=None):
"""Fetch many rows, just like DB-API
@@ -772,7 +769,6 @@ class ResultProxy(object):
self.connection._handle_dbapi_exception(
e, None, None,
self.cursor, self.context)
- raise
def fetchone(self):
"""Fetch one row, just like DB-API ``cursor.fetchone()``.
@@ -792,7 +788,6 @@ class ResultProxy(object):
self.connection._handle_dbapi_exception(
e, None, None,
self.cursor, self.context)
- raise
def first(self):
"""Fetch the first row and then close the result set unconditionally.
@@ -809,7 +804,6 @@ class ResultProxy(object):
self.connection._handle_dbapi_exception(
e, None, None,
self.cursor, self.context)
- raise
try:
if row is not None: