SQLAlchemy会话和连接关系

时间:2016-02-24 06:20:48

标签: python mysql sqlalchemy locking

使用相同的SQLAlchemy session对象执行的查询是否使用相同的底层连接?如果没有,有没有办法确保这一点?

一些背景知识:我需要使用MySQL的命名锁定功能,即GET_LOCK()RELEASE_LOCK()功能。就MySQL服务器而言,只有获得锁的连接才能释放它 - 因此我必须确保在同一连接中执行这两个命令或连接死亡以确保锁被释放。

为了让事情变得更好,我创造了一个锁定的"上下文如此:

@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

我想确保execute中的两个mysql_named_lock调用发生在同一个底层连接上,或者连接已关闭。

我可以假设这会“#34;只是工作"或者我需要注意什么?

1 个答案:

答案 0 :(得分:3)

如果(a)你的会话是scoped_session而且(b)你以非并发的方式使用它(相同的pid /线程),它将“正常工作”。如果你太偏执了,请确保(断言)你通过

使用相同的连接ID
session.connection().connection.thread_id()

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