This recipe lets databaseconnections live in their own thread and queues are used to communicate with them.
1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 | importpysqlite2.dbapi2assqliteimportQueue,time,thread,osfromthreadingimportThread_threadex=thread.allocate_lock()qthreads=0sqlqueue=Queue.Queue()ConnectCmd="connect"SqlCmd="SQL"StopCmd="stop"classDbCmd:def__init__(self,cmd,params=[]):self.cmd=cmdself.params=paramsclassDbWrapper(Thread):def__init__(self,path,nr):Thread.__init__(self)self.path=pathself.nr=nrdefrun(self):globalqthreadscon=sqlite.connect(self.path)cur=con.cursor()whileTrue:s=sqlqueue.get()print"Conn%d ->%s ->%s"%(self.nr,s.cmd,s.params)ifs.cmd==SqlCmd:commitneeded=Falseres=[]# s.params is a list to bundle statements into a "transaction"forsqlins.params:cur.execute(sql[0],sql[1])ifnotsql[0].upper().startswith("SELECT"):commitneeded=Trueforrowincur.fetchall():res.append(row)ifcommitneeded:con.commit()s.resultqueue.put(res)else:_threadex.acquire()qthreads-=1_threadex.release()# allow other threads to stopsqlqueue.put(s)s.resultqueue.put(None)breakdefexecSQL(s):ifs.cmd==ConnectCmd:globalqthreads_threadex.acquire()qthreads+=1_threadex.release()wrap=DbWrapper(s.params,qthreads)wrap.start()elifs.cmd==StopCmd:s.resultqueue=Queue.Queue()sqlqueue.put(s)# sleep until all threads are stoppedwhileqthreads>0:time.sleep(0.1)else:s.resultqueue=Queue.Queue()sqlqueue.put(s)returns.resultqueue.get()if__name__=="__main__":dbname="test.db"execSQL(DbCmd(ConnectCmd,dbname))execSQL(DbCmd(SqlCmd,[("create table people (name_last, age integer);",())]))# don't add connections before creating tableexecSQL(DbCmd(ConnectCmd,dbname))# insert one rowexecSQL(DbCmd(SqlCmd,[("insert into people (name_last, age) values (?, ?);",('Smith',80))]))# insert two rows in one transactionexecSQL(DbCmd(SqlCmd,[("insert into people (name_last, age) values (?, ?);",('Jones',55)),("insert into people (name_last, age) values (?, ?);",('Gruns',25))]))forpinexecSQL(DbCmd(SqlCmd,[("select * from people",())])):printpexecSQL(DbCmd(StopCmd))os.remove(dbname) |
(py)SQLite restricts use of a connection to the database to the thread that it was created in. This recipe facilitates use of (py)SQLite from webapplications (like cherrypy), without the need to connect to the database for every SQL-command.
| Created byWim SchutonThu, 15 Jun 2006(PSF) |
| ◄ | Python recipes (4591) | ► |
| ◄ | Wim Schut's recipes (1) | ► |
Privacy Policy |Contact Us |Support
© 2024 ActiveState Software Inc. All rights reserved. ActiveState®, Komodo®, ActiveState Perl Dev Kit®, ActiveState Tcl Dev Kit®, ActivePerl®, ActivePython®, and ActiveTcl® are registered trademarks of ActiveState. All other marks are property of their respective owners.