【发布时间】:2013-02-14 22:33:53
【问题描述】:
我在一个 sqlite 数据库中有两个简单的表。
from sqlalchemy import MetaData, Table, Column, Integer, ForeignKey, \
create_engine, String
from sqlalchemy.orm import mapper, relationship, sessionmaker, scoped_session
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('sqlite:///dir_graph.sqlite', echo=True)
session_factory = sessionmaker(bind=engine)
Session = scoped_session(session_factory)
session = Session()
Base = declarative_base()
class NodeType(Base):
__tablename__ = 'nodetype'
id = Column(Integer, primary_key=True)
name = Column(String(20), unique=True)
nodes = relationship('Node', backref='nodetype')
def __init__(self, name):
self.name = name
def __repr__(self):
return "Nodetype: %s" % self.name
class Node(Base):
__tablename__ = 'node'
id = Column(Integer, primary_key=True)
name = Column(String(20), unique=True)
type_id = Column(Integer,
ForeignKey('nodetype.id'))
def __init__(self, _name, _type_id):
self.name = _name
self.type_id = _type_id
Base.metadata.create_all(engine)
运行后我与解释器交互。例如n1= Node('Node1',1) 了解 sqlalchemy。在我做了一个 session.commit() 并尝试另一个语句之后,例如n2 = Node('n2',1) 我得到这个错误: sqlalchemy.exc.ProgrammingError: (ProgrammingError) 在一个线程中创建的 SQLite 对象只能在同一个线程中使用。该对象是在线程 id 3932 中创建的,这是线程 id 5740 无 无。
提交后如何继续会话? tnx
【问题讨论】:
-
该错误是一个 SQLite 驱动程序错误,正如它所说的那样,你不能在两个不同的线程中使用连接 - 这里还有更多的故事,你是如何运行会议在这里?有什么线程正在进行吗?
-
线程没有故意的。我在 Spyder 中运行此代码。运行设置是在运行后与解释器进行交互。这就是我所做的。看起来 commit() 关闭了连接,然后我重新初始化了。我没有在 SQLalchemy 文档中找到 excat 提示。
-
尝试在默认的 Python 解释器中运行或作为单个脚本运行。从未听说过“Spyder”,但它可能会用线程做一些奇怪的事情。
-
嗨@zzzeek,我认为这种情况发生了很多。特别是对于密集使用 TwistedThread 延迟机制的应用程序。我整天都在试图解决这个案子。有什么建议我可以在扭曲的延迟线程中安全地使用 sqlalchemy 吗?
-
以前从未使用过 twisted,但您需要确保特定的 SQLAlchemy 会话保持与单个操作系列挂钩,并且不会与执行不同操作的其他系列操作共享。 “线程本地”会话可能适合也可能不适合twisted 的线程池。当人们尝试使用带 twisted 的普通库时,我毫不怀疑这个问题经常发生,因为将 twisted 与线程代码混合使用必然需要对并发有相当程度的熟悉。
标签: sqlite sqlalchemy