Issue 1:
Migrated issue, originally created by Michael Bayer (@zzzeek)

despite all the "Safe reraise" and everything, I'm still not seeing the original cause here when I illustrate a variant of #3532:

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class A(Base):
__tablename__ = 'a'
id = Column(Integer, primary_key=True)
bs = relationship("B")

class B(Base):
__tablename__ = 'b'
id = Column(Integer, primary_key=True)
a_id = Column(ForeignKey('a.id'), nullable=False)

class C(Base):
__tablename__ = 'c'

id = Column(Integer, primary_key=True)
a_id = Column(ForeignKey('a.id'))
a1 = relationship("A")
a2 = a1

e = create_engine("sqlite://", echo=True)
Base.metadata.create_all(e)

s = Session(e)

s.add(C())
s.commit()
c1 = s.query(C).first()

s.add(B())

s.query(A).get(1)

#!

2015-09-17 10:42:02,198 INFO sqlalchemy.engine.base.Engine ROLLBACK
Traceback (most recent call last):
File "test.py", line 37, in <module>
s.query(A).get(1)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/query.py", line 831, in get
return self._get_impl(ident, loading.load_on_ident)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/query.py", line 864, in _get_impl
return fallback_fn(self, key)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/loading.py", line 223, in load_on_ident
return q.one()
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/query.py", line 2498, in one
ret = list(self)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/query.py", line 2540, in __iter__
self.session._autoflush()
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/session.py", line 1283, in _autoflush
self.flush()
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/session.py", line 2024, in flush
self._flush(objects)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/session.py", line 2142, in _flush
transaction.rollback(_capture_exception=True)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/util/langhelpers.py", line 63, in __exit__
compat.reraise(type_, value, traceback)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/session.py", line 2142, in _flush
transaction.rollback(_capture_exception=True)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/session.py", line 415, in rollback
transaction._rollback_impl()
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/session.py", line 448, in _rollback_impl
self._restore_snapshot(dirty_only=self.nested)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/session.py", line 290, in _restore_snapshot
s._expire(s.dict, self.session.identity_map._modified)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/state.py", line 523, in _expire
[impl.key for impl in self.manager._scalar_loader_impls
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/util/langhelpers.py", line 747, in __get__
obj.__dict__[self.__name__] = result = self.fget(obj)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/instrumentation.py", line 111, in _scalar_loader_impls
self.values() if attr.impl.accepts_scalar_loader])
AttributeError: 'NoneType' object has no attribute 'accepts_scalar_loader'

between this and that we're seeing #2696 variants come up in openstack we need to squash these rollback-related errors once and for all

Issue 2:
Migrated issue, originally created by Anonymous

We got weird ("(OperationalError) (1305, 'SAVEPOINT sa_savepoint_1 does not exist') in our prod, and after investigation, this is due to the fact that our mysql server fails a commit (we don't know why), and the handling of that exception in sqlalchemy leads to an automatic rollback to last savepoint. But that auto-rollback fails too (probably because mysql has already automatically rolled back by itself, and so destroyed savepoints), and thus the new exception "SAVEPOINT does not exist" hides the original error that caused all that trouble.

Here is the faulting code line, in latest development branch, in sqlalchemy/orm/session.py, line 1930:

except:
transaction.rollback(_capture_exception=True)
raise

Since we don't know the actual state of the mysql transaction at that moment, I guess that this automatic rollback should be protected by a try...except, so that if it fails, it's the original error that will be reraised in any case. Or shouldn't it ?

Here is the full traceback we got in prod (with sqlalchemy 0.7.3, but the faulty lines are still present in latest sqlalchemy versions):

File "/home/pimsprod/PIMS/src/pims/processing/processor_abstract.py", line 213, in retrieve_user
session.commit() # COMMIT SAVEPOINT
File "/home/pimsprod/PIMS/src/pims/database_tools.py", line 85, in commit
super(SafeSessionClass, self).commit(*args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 645, in commit
self.transaction.commit()
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 313, in commit
self._prepare_impl()
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 297, in _prepare_impl
self.session.flush()
File "/home/pimsprod/PIMS/src/pims/database_tools.py", line 77, in flush
super(SafeSessionClass, self).flush(*args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 1547, in flush
self._flush(objects)
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 1634, in _flush
transaction.rollback(_capture_exception=True)
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 338, in rollback
transaction._rollback_impl()
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 356, in _rollback_impl
t[1](1).rollback()
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1960, in rollback
self._do_rollback()
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 2020, in _do_rollback
self._savepoint, self._parent)
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1249, in _rollback_to_savepoint_impl
self.engine.dialect.do_rollback_to_savepoint(self, name)
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/default.py", line 321, in do_rollback_to_savepoint
connection.execute(expression.RollbackToSavepointClause(name))
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1399, in execute
params)
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1532, in _execute_clauseelement
compiled_sql, distilled_params
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1640, in _execute_context
context)
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1633, in _execute_context
context)
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/default.py", line 330, in do_execute
cursor.execute(statement, parameters)
File "/usr/local/lib/python2.7/site-packages/MySQLdb/cursors.py", line 174, in execute
self.errorhandler(self, exc, value)
File "/usr/local/lib/python2.7/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
OperationalError: (OperationalError) (1305, 'SAVEPOINT sa_savepoint_1 does not exist') 'ROLLBACK TO SAVEPOINT sa_savepoint_1' ()