Python 多线程上的sqlalchemy连接池
首先,我创建一个简单的表Python 多线程上的sqlalchemy连接池,python,multithreading,python-3.x,sqlalchemy,Python,Multithreading,Python 3.x,Sqlalchemy,首先,我创建一个简单的表 import threading from sqlalchemy import create_engine from sqlalchemy import Column, Integer, Float, String, Date, DateTime, Boolean, select from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.pool import SingletonThr
import threading
from sqlalchemy import create_engine
from sqlalchemy import Column, Integer, Float, String, Date, DateTime, Boolean, select
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.pool import SingletonThreadPool
from sqlalchemy.orm import scoped_session
from sqlalchemy.orm import sessionmaker
inven_schema = {'__tablename__' : 'inventory',
'item_no' : Column(Integer, primary_key=True, autoincrement=True),
'desc' : Column(String(255), nullable=False),
'volume' : Column(Integer, nullable=False)
}
Base = declarative_base()
# Dynamically create Inventory for ORM
Inventory = type('Inventory', (Base,), inven_schema)
some_inventory = [{'item_no' : 0, 'desc' : 'toy crane', 'volume' : 12},
{'item_no' : 1, 'desc' : 'puddle jumper', 'volume' : 2},
{'item_no' : 2, 'desc' : 'pet snake', 'volume' : 1},
{'item_no' : 3, 'desc' : 'bowling ball', 'volume' : 4},
{'item_no' : 4, 'desc' : 'spinning top', 'volume' : 3},
{'item_no' : 5, 'desc' : 'pumpkin', 'volume' : 2}]
但是如果会话和插入在不同的线程上,我就不能让它工作。这是我的尝试,它抛出:
File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/util/compat.py", line 203, in raise_from_cause
reraise(type(exception), exception, tb=exc_tb, cause=cause)
File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/util/compat.py", line 186, in reraise
raise value.with_traceback(tb)
File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/engine/base.py", line 1159, in _execute_context
context)
File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/engine/default.py", line 467, in do_executemany
cursor.executemany(statement, parameters)
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: inventory [SQL: 'INSERT INTO inventory (item_no, "desc", volume) VALUES (?, ?, ?)'] [parameters: ((0, 'toy crane', 12), (1, 'puddle jumper', 2), (2, 'pet snake', 1), (3, 'bowling ball', 4), (4, 'spinning top', 3), (5, 'pumpkin', 2))]
我已经尝试在线程调用中创建会话,以及其他一些变体。我应该如何修改以下方法
def insert_inventory(inventory, session):
inventory_ = [Inventory(**inven) for inven in inventory]
session.add_all(inventory_)
session.commit()
def results(session):
q = select([Inventory.item_no]).distinct(Inventory.item_no)
distinct_items = session.execute(q).fetchall()
print('{!r}'.format(distinct_items))
def demo2():
engine = create_engine('sqlite://')
conn = engine.connect()
Base.metadata.create_all(conn.engine)
session_factory = sessionmaker(bind=conn.engine)
Session = scoped_session(session_factory)
session = Session()
thread_0 = threading.Thread(target=insert_inventory, args=(some_inventory, session))
thread_0.start()
session.close()
results(session)
我无法在session()
级别执行add()
或add_all()
。如果使用附加参数创建引擎()
,则以下操作有效
我认为这是序列化对SQLite3DB表的调用,这对sqlite来说并不理想,但却是必需的
engine = create_engine('sqlite://', connect_args={'check_same_thread' : False})
conn = engine.connect()
metadata = MetaData(engine)
table = Table('inventory',
metadata,
Column('item_no', Integer, primary_key=True, autoincrement=True),
Column('desc', String(255), nullable=False),
Column('volume', Integer, nullable=False)
)
metadata.create_all()
some_inventory = [{'item_no' : 0, 'desc' : 'toy crane', 'volume' : 12},
{'item_no' : 1, 'desc' : 'puddle jumper', 'volume' : 2},
{'item_no' : 2, 'desc' : 'pet snake', 'volume' : 1},
{'item_no' : 3, 'desc' : 'bowling ball', 'volume' : 4},
{'item_no' : 4, 'desc' : 'spinning top', 'volume' : 3},
{'item_no' : 5, 'desc' : 'pumpkin', 'volume' : 2}]
thread_0 = threading.Thread(target=insert_inventory_table, args=(conn, table, some_inventory[0:3]))
thread_1 = threading.Thread(target=insert_inventory_table, args=(conn, table, some_inventory[3:]))
thread_0.start()
thread_1.start()
我无法在session()
级别执行add()
或add_all()
。如果使用附加参数创建引擎()
,则以下操作有效
我认为这是序列化对SQLite3DB表的调用,这对sqlite来说并不理想,但却是必需的
engine = create_engine('sqlite://', connect_args={'check_same_thread' : False})
conn = engine.connect()
metadata = MetaData(engine)
table = Table('inventory',
metadata,
Column('item_no', Integer, primary_key=True, autoincrement=True),
Column('desc', String(255), nullable=False),
Column('volume', Integer, nullable=False)
)
metadata.create_all()
some_inventory = [{'item_no' : 0, 'desc' : 'toy crane', 'volume' : 12},
{'item_no' : 1, 'desc' : 'puddle jumper', 'volume' : 2},
{'item_no' : 2, 'desc' : 'pet snake', 'volume' : 1},
{'item_no' : 3, 'desc' : 'bowling ball', 'volume' : 4},
{'item_no' : 4, 'desc' : 'spinning top', 'volume' : 3},
{'item_no' : 5, 'desc' : 'pumpkin', 'volume' : 2}]
thread_0 = threading.Thread(target=insert_inventory_table, args=(conn, table, some_inventory[0:3]))
thread_1 = threading.Thread(target=insert_inventory_table, args=(conn, table, some_inventory[3:]))
thread_0.start()
thread_1.start()
你能说得更具体些吗?正如我所指出的,第一次尝试是不正确的。基本上,每个线程都应该有自己的会话/连接,您可以在每个线程内创建一个新的会话/连接,或者使用sqlalchemy中的作用域_会话/连接池。好的,这更有意义,我将尝试。您能更具体一些吗?正如我所指出的,第一次尝试是不正确的。基本上,每个线程都应该有自己的会话/连接,您可以在每个线程内创建一个新的会话/连接,或者使用sqlalchemy中的作用域会话/连接池。好的,我将尝试这样做。