Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQLAlchemy不将Python池线程识别为独立进程_Python_Database_Multithreading_Sqlalchemy - Fatal编程技术网

SQLAlchemy不将Python池线程识别为独立进程

SQLAlchemy不将Python池线程识别为独立进程,python,database,multithreading,sqlalchemy,Python,Database,Multithreading,Sqlalchemy,我正在尝试将我的单线程应用程序转换为使用SQLAlchemy数据库的多线程应用程序。我发现SQLAlchemy会话不是线程安全的。因此,我们需要使用作用域_会话工厂进行线程安全的数据库访问 下面是我的输入数据集 input_list = [data1, data2, data3, data4, data5] 单线程应用程序 from sqlalchemy.orm import sessionmaker, scoped_session Session = sessionmaker(bind=en

我正在尝试将我的单线程应用程序转换为使用SQLAlchemy数据库的多线程应用程序。我发现SQLAlchemy会话不是线程安全的。因此,我们需要使用作用域_会话工厂进行线程安全的数据库访问

下面是我的输入数据集

input_list = [data1, data2, data3, data4, data5]
单线程应用程序

from sqlalchemy.orm import sessionmaker, scoped_session
Session = sessionmaker(bind=engine_url)

for data in input_list:
    def myfunction(data):
        db_session = Session()
        print(db_session)
        # use db_session to query/store the data
from sqlalchemy.orm import sessionmaker, scoped_session
Session = scoped_session(sessionmaker(bind=engine_url))

def myfunction(data):
    db_session = Session()
    print(db_session)
    # use db_session to query/store the data

def myfunction_parallel():
    with ThreadPool(4) as pool:
        output = pool.map(myfunction, input_list)
当我尝试将其转换为多线程应用程序时

from sqlalchemy.orm import sessionmaker, scoped_session
Session = sessionmaker(bind=engine_url)

for data in input_list:
    def myfunction(data):
        db_session = Session()
        print(db_session)
        # use db_session to query/store the data
from sqlalchemy.orm import sessionmaker, scoped_session
Session = scoped_session(sessionmaker(bind=engine_url))

def myfunction(data):
    db_session = Session()
    print(db_session)
    # use db_session to query/store the data

def myfunction_parallel():
    with ThreadPool(4) as pool:
        output = pool.map(myfunction, input_list)

在多线程变体中,我将
db_session
作为同一个对象,但我的期望是应该为每个线程创建一个新的会话对象,并且会话应该不同?

范围会话注册表为每个请求会话的线程注册会话。这使代码能够调用
db\u session=session()
,并获取线程的预期会话

但是,当不再需要会话时,应用程序有责任通知会话注册表。应用程序通过调用
Session.remove()
来执行此操作,如文档所示:

scoped_session.remove()方法首先在当前会话上调用session.close(),其效果是首先释放会话拥有的所有连接/事务资源,然后丢弃会话本身。这里的“释放”意味着连接被返回到它们的连接池,任何事务状态都被回滚,最终使用底层DBAPI连接的rollback()方法

此时,作用域_会话对象为“空”,再次调用时将创建一个新会话

此代码应按预期工作:

def myfunction(数据):
db_session=session()
打印(db_会话)
#使用db_会话查询/存储数据
Session.remove()

另外,如果在创建第二个会话之前创建和清理一个会话并执行线程,则四个不同的会话对象完全可能具有相同的对象ID。(对于会话所在的代码,这是完全可能的。只在这么短的范围内。)在创建会话和打印会话之间添加一个
sleep(1)
,以强制线程在会话对象可以GCed(释放其对象ID)之前屈服,并查看您是否仍然获得相同的对象ID。