SQLAlchemy 是否从同一连接重置 SQLAlchemy 会话之间的数据库会话?
Does SQLAlchemy reset the database session between SQLAlchemy Sessions from the same connection?
SQLAlchemy 使用连接池。这意味着相同的连接可以在不同的 SQLAlchemy 会话中重复使用。但是,单个 SQLAlchemy 会话包含在其自身中并在关闭后被丢弃。但是,连接保持 'active'.
我想将一些东西保存到 Postgresql 的数据库会话存储中,使用 set_config:
PERFORM set_config('session.storage', 'remember-me-across-this-session', false)
现在,这是在数据库会话的范围内。我的问题是:当 SQLAlchemy 使用 相同的连接 创建一个新的 SQLAlchemy 会话时,这是否也会创建一个新的数据库会话,或者该连接是否会在其生命周期内重复使用相同的数据库会话?
注意:
我已经尝试通过将所有相关池大小设置为最小值(max_overflow 0,pool_size 1,pool_recycle 600)然后 运行 以下脚本(简化):
print(DBSESSION.execute(text("SELECT set_config('session.storage', 'remember-me-across-this-session', false)")).first())
print(DBSESSION.execute(text("SELECT current_setting('session.storage')")).first())
transaction.commit()
DBSESSION.close()
for _ in range(5):
print(DBSESSION.execute(text("SELECT current_setting('session.storage')")).first())
transaction.commit()
DBSESSION.close()
此测试没有“记住”循环中后续会话的第一行中设置的值,因此确认数据库会话确实在同一连接的 SQLAlchemy 会话之间重置。然而,因为这是逻辑的关键部分,我希望得到第二意见/肯定,以确保我没有搞砸。
1。 SQLAlchemy 是否重置数据库会话?
不,不是。
1.1。关于 SQLAlchemy 会话
SQLAlchemy session.close()
关闭剩余的 SQLAlchemy 事务,这些事务在它们的连接上调用 ROLLBACK
并将它们 return 到池中。
来自 How to close a SQLAlchemy session:
A SQLAlchemy Session generally represents the scope of one or more transactions, upon a particular database connection.
1.2。关于 PostgreSQL 会话
来自 :
a session is "synonymous with a TCP connection".
1.3。关于 PostgreSQL SET
来自 https://www.postgresql.org/docs/9.3/sql-set.html:
If SET
(or equivalently SET SESSION
) is issued within a transaction that is later aborted, the effects of the SET
command disappear when the transaction is rolled back. Once the surrounding transaction is committed, the effects will persist until the end of the session, unless overridden by another SET
.
2。为什么问题中的测试有效?
在测试中,没有任何操作导致 Zope 将会话状态标记为已更改。
Zope transaction.commit()
检查会话状态是否改变:
- 如果不是,它调用 SQLAlchemy
session.close()
并将其对 SQLAlchemy 事务的引用设置为 None
。
- 如 1.1 中所述。关于 SQLAlchemy 会话 ,这会在连接上调用
ROLLBACK
。
- 如 1.3 中所述。关于PostgreSQL
SET
,SET
命令的效果消失。
- 否则,它会提交 SQLAlchemy 事务。
- 如 1.3 中所述。关于 PostgreSQL
SET
,效果将持续到 (PostgreSQL) 会话结束。
您可以通过明确将会话标记为已更改来验证 Else
案例:
print(DBSESSION.execute(text("SELECT set_config('session.storage', 'remember-me-across-this-session', false)")).first())
print(DBSESSION.execute(text("SELECT current_setting('session.storage')")).first())
mark_changed(DBSESSION.registry()) # Add this
transaction.commit()
注意:由于 transaction.commit()
和 transaction.abort()
已经隐式调用 session.close()
,因此对 DBSESSION.close()
的后续调用实际上什么都不做。
3。如何重置会话运行-时间参数?
为 sqlalchemy.events.PoolEvents.checkin
and call RESET
添加事件侦听器。
@event.listens_for(engine, 'checkin')
def receive_checkin(dbapi_connection, connection_record):
cursor = dbapi_connection.cursor()
cursor.execute('RESET session.storage')
# cursor.execute('RESET ALL')
SQLAlchemy 使用连接池。这意味着相同的连接可以在不同的 SQLAlchemy 会话中重复使用。但是,单个 SQLAlchemy 会话包含在其自身中并在关闭后被丢弃。但是,连接保持 'active'.
我想将一些东西保存到 Postgresql 的数据库会话存储中,使用 set_config:
PERFORM set_config('session.storage', 'remember-me-across-this-session', false)
现在,这是在数据库会话的范围内。我的问题是:当 SQLAlchemy 使用 相同的连接 创建一个新的 SQLAlchemy 会话时,这是否也会创建一个新的数据库会话,或者该连接是否会在其生命周期内重复使用相同的数据库会话?
注意: 我已经尝试通过将所有相关池大小设置为最小值(max_overflow 0,pool_size 1,pool_recycle 600)然后 运行 以下脚本(简化):
print(DBSESSION.execute(text("SELECT set_config('session.storage', 'remember-me-across-this-session', false)")).first())
print(DBSESSION.execute(text("SELECT current_setting('session.storage')")).first())
transaction.commit()
DBSESSION.close()
for _ in range(5):
print(DBSESSION.execute(text("SELECT current_setting('session.storage')")).first())
transaction.commit()
DBSESSION.close()
此测试没有“记住”循环中后续会话的第一行中设置的值,因此确认数据库会话确实在同一连接的 SQLAlchemy 会话之间重置。然而,因为这是逻辑的关键部分,我希望得到第二意见/肯定,以确保我没有搞砸。
1。 SQLAlchemy 是否重置数据库会话?
不,不是。
1.1。关于 SQLAlchemy 会话
SQLAlchemy session.close()
关闭剩余的 SQLAlchemy 事务,这些事务在它们的连接上调用 ROLLBACK
并将它们 return 到池中。
来自 How to close a SQLAlchemy session:
A SQLAlchemy Session generally represents the scope of one or more transactions, upon a particular database connection.
1.2。关于 PostgreSQL 会话
来自
a session is "synonymous with a TCP connection".
1.3。关于 PostgreSQL SET
来自 https://www.postgresql.org/docs/9.3/sql-set.html:
If
SET
(or equivalentlySET SESSION
) is issued within a transaction that is later aborted, the effects of theSET
command disappear when the transaction is rolled back. Once the surrounding transaction is committed, the effects will persist until the end of the session, unless overridden by anotherSET
.
2。为什么问题中的测试有效?
在测试中,没有任何操作导致 Zope 将会话状态标记为已更改。
Zope transaction.commit()
检查会话状态是否改变:
- 如果不是,它调用 SQLAlchemy
session.close()
并将其对 SQLAlchemy 事务的引用设置为None
。- 如 1.1 中所述。关于 SQLAlchemy 会话 ,这会在连接上调用
ROLLBACK
。- 如 1.3 中所述。关于PostgreSQL
SET
,SET
命令的效果消失。
- 如 1.3 中所述。关于PostgreSQL
- 如 1.1 中所述。关于 SQLAlchemy 会话 ,这会在连接上调用
- 否则,它会提交 SQLAlchemy 事务。
- 如 1.3 中所述。关于 PostgreSQL
SET
,效果将持续到 (PostgreSQL) 会话结束。
- 如 1.3 中所述。关于 PostgreSQL
您可以通过明确将会话标记为已更改来验证 Else
案例:
print(DBSESSION.execute(text("SELECT set_config('session.storage', 'remember-me-across-this-session', false)")).first())
print(DBSESSION.execute(text("SELECT current_setting('session.storage')")).first())
mark_changed(DBSESSION.registry()) # Add this
transaction.commit()
注意:由于 transaction.commit()
和 transaction.abort()
已经隐式调用 session.close()
,因此对 DBSESSION.close()
的后续调用实际上什么都不做。
3。如何重置会话运行-时间参数?
为 sqlalchemy.events.PoolEvents.checkin
and call RESET
添加事件侦听器。
@event.listens_for(engine, 'checkin')
def receive_checkin(dbapi_connection, connection_record):
cursor = dbapi_connection.cursor()
cursor.execute('RESET session.storage')
# cursor.execute('RESET ALL')