未创建Python Peewee SqliteQueueDatabase表

2024-10-03 23:24:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用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示例,但无法找到。在


Tags: from文档import数据库应用程序dbsqlitetables
3条回答

最后我做的是,除了sqlite3和threading之外,我没有使用peewee、SqliteQueueDatabase或任何ORM。在

使用一种单例技巧,我基本上有一个对象的一个实例,它有一个连接属性,因此一个连接实例被所有线程共享。当连接到sqlite时,我必须设置check_same_thread=False,否则不同的线程不能共享同一个连接。在

以下是简化版本:

import sqlite3
import threading

class Singleton(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]

class Dao(object, metaclass=Singleton):

    def __init__(self, conf=None):
        self.lock = threading.Lock()
        self.conn = sqlite3.connect(
                conf.db,
                check_same_thread=False
            )

我第一次在主线程中实例化Dao类并将配置传递给__init__。后来无论哪个线程需要使用数据库,它都只创建了一个Dao对象。但是由于Singleton技巧,调用者只获得了对已经存在的实例的引用,该实例还包括已经建立的连接。在

我将所有的DB操作作为方法添加到这个Dao类中。为了避免重复锁定,我使用wraps创建了装饰器。在

^{pr2}$

对于只读操作,我有一个类似的包装器,但是没有提交/回滚。我在其中设置了是否在只读操作期间执行锁定的配置,只是为了能够在prod中发生DB并发问题时在不需要新版本的情况下调整锁定行为

现在我所要做的就是将我的自定义事务装饰器添加到Dao方法中。(在现实生活中,事务可以由几个SQL命令组成。因此,我有一些没有事务注释的原子方法,它们从来没有直接从外部调用。它们只由其他一些Dao方法调用,这些方法在单个事务中执行多个调用,因此这些复杂的方法具有事务注释。对于这些事务的大小和速度,我非常小心,因为在我的例子中,锁机制基本上阻止了其他线程同时处理数据库。)

因此Dao方法可以类似于:

@transaction_read_write
def set_processed_files(self, id, num_files):
    cur = self.conn.cursor()
    cur.execute("UPDATE jobs SET num_files = ? WHERE job_id = ?", (num_files, id))

最后,我决定不使用peewee,但我希望在我的示例中有一些有用的东西。在

我遇到过这个问题,似乎read查询在create_tables()之前完成。在

我的解决方法是抛出连续的db.stop()db.start()调用。强制代码执行等待所有数据库写入查询完成。在

from peewee import *
from playhouse.sqliteq import SqliteQueueDatabase

db = SqliteQueueDatabase('db.sqlite3')


class Prime(Model):
    num = IntegerField()

class Meta:
    database = db


db.start()
db.connect()
db.create_tables([Prime])
db.stop() #  Wait for create_tables() to complete
db.start() #  Continue execution
print db.get_tables()
db.stop()

你正在使用内存数据库。内存中的数据库对每个线程使用一个连接。因此,除非您特别使用共享内存模式(您必须查阅sqlite文档),否则您就走运了。在

使用基于文件的数据库,您的示例将运行良好。在

相关问题 更多 >