我正在用SQLite数据库开发一个多线程应用程序。我做了一些研究,看来SqliteQueueDatabase可以提供所需的并发处理。我仔细阅读了文档,但似乎还没有完全了解如何启动和启动数据库。在
from peewee import *
from playhouse.sqliteq import SqliteQueueDatabase
db = SqliteQueueDatabase(':memory:')
class Prime(Model):
num = IntegerField()
class Meta:
database = db
db.start()
db.connect()
db.create_tables([Prime])
print db.get_tables() # prints []
db.stop()
在我的例子中,我并没有在我的表中创建这个模型,但是我并没有尝试在上面的例子中创建它。我错过了什么?我试图找到一个涵盖整个生命周期的peewee&SqliteQueueDatabase示例,但无法找到。在
最后我做的是,除了sqlite3和threading之外,我没有使用peewee、SqliteQueueDatabase或任何ORM。在
使用一种单例技巧,我基本上有一个对象的一个实例,它有一个连接属性,因此一个连接实例被所有线程共享。当连接到sqlite时,我必须设置
check_same_thread=False
,否则不同的线程不能共享同一个连接。在以下是简化版本:
我第一次在主线程中实例化
Dao
类并将配置传递给__init__
。后来无论哪个线程需要使用数据库,它都只创建了一个Dao
对象。但是由于Singleton技巧,调用者只获得了对已经存在的实例的引用,该实例还包括已经建立的连接。在我将所有的DB操作作为方法添加到这个
^{pr2}$Dao
类中。为了避免重复锁定,我使用wraps
创建了装饰器。在对于只读操作,我有一个类似的包装器,但是没有提交/回滚。我在其中设置了是否在只读操作期间执行锁定的配置,只是为了能够在prod中发生DB并发问题时在不需要新版本的情况下调整锁定行为
现在我所要做的就是将我的自定义事务装饰器添加到
Dao
方法中。(在现实生活中,事务可以由几个SQL命令组成。因此,我有一些没有事务注释的原子方法,它们从来没有直接从外部调用。它们只由其他一些Dao
方法调用,这些方法在单个事务中执行多个调用,因此这些复杂的方法具有事务注释。对于这些事务的大小和速度,我非常小心,因为在我的例子中,锁机制基本上阻止了其他线程同时处理数据库。)因此
Dao
方法可以类似于:最后,我决定不使用peewee,但我希望在我的示例中有一些有用的东西。在
我遇到过这个问题,似乎read查询在
create_tables()
之前完成。在我的解决方法是抛出连续的
db.stop()
db.start()
调用。强制代码执行等待所有数据库写入查询完成。在你正在使用内存数据库。内存中的数据库对每个线程使用一个连接。因此,除非您特别使用共享内存模式(您必须查阅sqlite文档),否则您就走运了。在
使用基于文件的数据库,您的示例将运行良好。在
相关问题 更多 >
编程相关推荐