我的设计思想是,“数据库对象”将实现某些方法,在查询并检查了相关值之后,我想将此实例传递给threading.Thread()并在不同线程中执行一些代码。我想为此使用scoped_session。
问题在于实例包含会话对象,因此它引发异常:
sqlite3.ProgrammingError:在线程中创建的SQLite对象只能 在同一线程中使用。该对象是在线程ID中创建的 140081404675584,这是线程ID 140081133512448。
db_alchemy / __ init __。py:
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import scoped_session, sessionmaker
Base = declarative_base()
e = create_engine("sqlite:///datafiles/data.sqlite")
Base.metadata.create_all(e)
Session = scoped_session(sessionmaker(bind=e))
db_alchemy / tables.py:
import threading
from sqlalchemy import Column, Integer, String, ForeignKey, DateTime, Time
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.ext.declarative import declarative_base, declared_attr
from sqlalchemy.orm import relationship, backref
from db_alchemy import Base, Session
class Request(Base):
__tablename__ = 'request'
id = Column(Integer, primary_key=True)
scan_title = Column(String)
status = Column(String)
servers = association_proxy('request_servers','server')
def print_servers(self):
print(threading.current_thread())
print(self.servers)
class Server(Base):
__tablename__ = 'server'
ip = Column(String, primary_key=True, autoincrement=False)
class Request2Server(Base):
__tablename__ = 'request2server'
request_id_fk = Column(Integer, ForeignKey('request.id'), primary_key=True)
server_ip_fk = Column(String, ForeignKey('server.ip'), primary_key=True)
request_rel = relationship('Request', backref=backref('request_servers',lazy='dynamic'))
server = relationship('Server', backref=backref('server_requests',lazy='dynamic'))
def __init__(self, server=None):
self.server = server
runner.py:
import threading
from threading import Thread
import db_alchemy.tables as t
from db_alchemy import Session, Base, e
if __name__ == '__main__':
Base.metadata.drop_all(e)
Base.metadata.create_all(e)
ses = Session()
r1 = t.Request(scan_title='R1', status='running')
r2 = t.Request(scan_title='R2', status='finished')
s1 = t.Server(ip='IP1')
s2 = t.Server(ip='IP2')
r1.servers.append(s1)
r1.servers.append(s2)
r2.servers.append(s2)
ses.add_all([r1, r2])
ses.commit()
for request in ses.query(t.Request).filter(t.Request.status == 'running').all():
print(threading.current_thread())
r1.print_servers()
Thread(target=r1.print_servers).start()
在设计中是否可以避免此错误? 我应该实现一些不同的设计吗?