On 08/10/2016 09:01 PM, Frazer McLean wrote:
SQLAlchemy v1.1b3 on Python 3.5.2
Is it expected behaviour that in this MVCE the deleted object does not
become detached after the final commit?
The term "final commit" is misleading here since that's not a
transaction COMMIT, that's just a release of a savepoint. If you remove
your event handler and place its steps inline, this is the equivalent
series of steps, so yes:
with session.begin_nested():
m1 = Model()
session.add(m1)
session.expire_all()
with session.begin_nested():
session.delete(m1)
session.flush()
assert inspect(m1).deleted
session.expire_all()
with session.begin_nested():
# if the nested transaction is rolled back,
# m1 goes back in. so not fully detached.
assert not inspect(m1).detached
# your script can never reach here due to the event handler
session.commit()
assert inspect(m1).detached
from sqlalchemy import create_engine, event, Column, Integer, inspect
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
def fix_sqlite(engine):
"""See
http://docs.sqlalchemy.org/en/rel_1_0/dialects/sqlite.html#pysqlite-serializable"""
@event.listens_for(engine, 'connect')
def do_connect(dbapi_connection, connection_record):
# disable pysqlite's emitting of the BEGIN statement entirely.
# also stops it from emitting COMMIT before any DDL.
dbapi_connection.isolation_level = None
@event.listens_for(engine, 'begin')
def do_begin(conn):
# emit our own BEGIN
conn.execute('BEGIN')
engine = create_engine('sqlite://', echo=True)
fix_sqlite(engine)
Session = sessionmaker(bind=engine)
Base = declarative_base()
class Model(Base):
__tablename__ = 'model'
id = Column(Integer, primary_key=True)
Base.metadata.create_all(bind=engine)
session = Session()
session.begin_nested()
@event.listens_for(session, 'after_transaction_end')
def restart_savepoint(session, transaction):
if transaction.nested and not transaction._parent.nested:
# ensure that state is expired the way
# session.commit() at the top level normally does
session.expire_all()
session.begin_nested()
m1 = Model()
session.add(m1)
session.commit()
session.delete(m1)
session.flush()
assert inspect(m1).deleted
session.commit()
assert inspect(m1).detached
--
You received this message because you are subscribed to the Google
Groups "sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to [email protected]
<mailto:[email protected]>.
To post to this group, send email to [email protected]
<mailto:[email protected]>.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.