为什么关闭的会话仍然可用?

Why is a closed session still usable?

为什么session关闭后仍然可用?如何正确关闭它?

@contextmanager
def session_scope():
    session = Session()
    try:
        yield session
        session.commit()
    except Exception as e:
        session.rollback()
        raise e
    finally:
        session.close()
        print('finally close session')

with session_scope() as session:
    query = session.query(Image)

# Before that, it has been output finally close session
a = query.filter(Image.id == 1).first()   # why can run 
print(a.id)
b = Image()
query.session.add(b)   # why can run
query.session.flush()
print(b.id)

这是预期的行为:关闭会话不会使其无法使用。来自 docs:

The Session.close() method issues a Session.expunge_all() which removes all ORM-mapped objects from the session, and releases any transactional/connection resources from the Engine object(s) to which it is bound. When connections are returned to the connection pool, transactional state is rolled back as well.

When the Session is closed, it is essentially in the original state as when it was first constructed, and may be used again. In this sense, the Session.close() method is more like a “reset” back to the clean state and not as much like a “database close” method.