在 Huey 中使用线程管理共享资源

Managing shared resources with threads in Huey

我必须更新 peewee 数据库 (SqliteDatabase) 中的许多行(每行增加一个值)。有些对象可以取消创建,因此我必须在使用它们之前使用默认值创建它们。我会使用 peewee 文档 (Atomic updates) 中的方法,但我不知道如何混合使用 model.get_or_create()in [my_array].

所以我决定在事务中进行查询以在最后提交一次(我希望它会)。

为什么我写在堆栈溢出是因为我不知道如何在 Huey 中使用 db.atomic() 线程(我测试了 4 个工人)因为 .atomic() 锁定了连接( peewee.OperationalError: database is locked)。我试过使用 @huey.lock_task,但我发现它不能解决我的问题。

我的代码 class:

class Article(Model):
    name = CharField()
    mention_number = IntegerField(default=0)

    class Meta:
        database = db

我的任务代码:

@huey.task(priority=30)
def update(names):  # "names" is a list of strings
    with db.atomic():
        for name in names:
            article, success = Article.get_or_create(name=name)
            article.mention_number += 1
            article.save()

好吧,如果您使用的是最新版本的 Sqlite(3.24 或更高版本),则可以使用 Postgres 样式的更新插入查询。 Peewee 对此提供了很好的支持:http://docs.peewee-orm.com/en/latest/peewee/api.html#Insert.on_conflict

要回答有关共享资源的其他问题,从您的示例中并不清楚您希望发生什么...Sqlite 一次只允许一个写入事务。因此,如果您是 运行 多个线程,那么在任何给定时间可能只有其中一个正在写入。

Peewee 在本地线程中存储数据库连接,因此 Peewee 数据库可以安全地用于多线程应用程序。

你没有提到为什么 huey lock_task 不起作用。

另一个建议是尝试将 WAL 模式与 Sqlite 一起使用,因为 WAL 模式允许多个 reader 事务与单个写入器共存。