SQLAlchemy会话和连接的关系

3
使用相同的SQLAlchemy session对象执行的查询是否使用相同的基础连接?如果不是,有没有办法确保这一点?
背景:我需要使用MySQL的命名锁定功能,即GET_LOCK()和RELEASE_LOCK()函数。就MySQL服务器而言,只有获得锁的连接才能释放它-因此,我必须确保在同一连接中执行这两个命令,或者连接断开以确保锁被释放。
为了使事情更好,我创建了一个“locked”上下文,如下所示:
@contextmanager
def mysql_named_lock(session, name, timeout):
    """Get a named mysql lock on a session
    """
    lock = session.execute("SELECT GET_LOCK(:name, :timeout)",
                           name=name, timeout=timeout).scalar()
    if lock:
        try:
            yield session
        finally:
            session.execute("SELECT RELEASE_LOCK(:name)", name=name)
    else:
        e = "Count not obtain named lock {} within {} sections".format(
            name, timeout)
        raise RuntimeError(e)

def my_critical_section(session):
    with mysql_named_lock(session, __name__, 10) as lockedsession:
        thing = lockedsession.query(MyStuff).one()
    return thing

我希望确保mysql_named_lock中的两个execute调用发生在同一个基础连接上或连接已关闭。

我能否假设这会“自动工作”,还是我需要注意一些事情?

1个回答

3

如果您的会话是scoped_session,并且您以非并发方式使用它,那么它将“正常工作”(即不需要额外配置)。如果您太过谨慎,请确保(assert)您通过相同的连接ID使用。

session.connection().connection.thread_id()

此外,在作为参数传递会话没有意义。在应用程序的全局范围内初始化它一次,然后在代码中任何地方调用它,您将获得相同的连接ID。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接