简体   繁体   English

与SQLite和Peewee同时写作

[英]Concurrent writes with SQLite and Peewee

I'm planning to use SQLite and Peewee (ORM) for a light duty internal web service (<20 requests per second). 我打算使用SQLite和Peewee(ORM)来实现轻量级内部Web服务(每秒<20个请求)。 The web service can handle multiple simultaneous requests on multiple threads. Web服务可以处理多个线程上的多个同时请求。 During each request the database will be both read from and written to. 在每个请求期间,数据库都将被读取和写入。 This means I will need to have the ability for both concurrent reads AND writes. 这意味着我需要具备并发读取和写入的能力。 It doesn't matter to this application if the data changes between reads and writes. 如果数据在读取和写入之间发生变化,则对此应用程序无关紧要。

The SQLite FAQ says that concurrent reads are permitted but concurrent writes from multiple threads require acquiring the file lock. SQLite FAQ表示允许并发读取,但来自多个线程的并发写入需要获取文件锁定。 My question is: Does Peewee take care of this locking for me or is there something I need to do in my code to make this possible? 我的问题是:Peewee是否会为我处理此锁定,或者我的代码中是否需要执行此操作以使其成为可能?

The Peewee database object is shared between threads. Peewee数据库对象在线程之间共享。 I assume this means that the database connection is shared too. 我认为这意味着数据库连接也是共享的。

I can't find a Peewee specific answer to this so I'm asking here. 我找不到Peewee对此的具体答案所以我在这里问。

Sqlite is the one doing the locking, although I can see how you might be confused -- the FAQ wording is a bit ambiguous: Sqlite是执行锁定的人,虽然我可以看到你可能会感到困惑 - 常见问题解答措辞有点模棱两可:

When any process wants to write, it must lock the entire database file for the duration of its update. 当任何进程想要写入时,它必须在更新期间锁定整个数据库文件。 But that normally only takes a few milliseconds. 但这通常只需要几毫秒。 Other processes just wait on the writer to finish then continue about their business. 其他流程只是等待作者完成然后继续他们的业务。 Other embedded SQL database engines typically only allow a single process to connect to the database at once. 其他嵌入式SQL数据库引擎通常只允许单个进程一次连接到数据库。

So if you have two threads, each with their own connection, and one acquires the write lock, the other thread will have to wait for the lock to be released before it can start writing. 因此,如果您有两个线程,每个线程都有自己的连接,并且一个获取写锁定,则另一个线程必须等待锁定才能开始写入。

Looking at pysqlite, the default busy timeout looks to be 5 seconds, so the second thread should wait up to 5 seconds before raising an OperationalError . 查看pysqlite,默认的busy超时看起来是5秒,因此第二个线程应该在提出OperationalError之前等待最多5秒。

Also, I'd suggest instantiating your SqliteDatabase with threadlocals=True . 另外,我建议用threadlocals=True实例化你的SqliteDatabase。 That will store a connection-per-thread. 这将存储每线程连接。

Consider to run all writing operations within 1 async process . 考虑在1个异步过程中运行所有写入操作 This made the Javascript server programming nowadays so famous (although this idea is know far longer). 这使得Javascript服务器编程如今如此着名(虽然这个想法知道得更久)。 It just needs that you a bit familiar with asynchronous programming concept of callbacks: 它只需要您熟悉回调的异步编程概念:

For SQLITE: 对于SQLITE:

For ANY DB. 对于任何数据库。

Consider to write your own thin async handler in python, as solved here eg SQLAlchemy + Requests Asynchronous Pattern I would recommend you the last approach, as this allows you more code portability, control, independance from the backend database engine and scalability. 考虑在python中编写自己的瘦异步处理程序,如此处解决,例如SQLAlchemy +请求异步模式我建议您使用最后一种方法,因为这样可以让您从后端数据库引擎和可扩展性中获得更多的代码可移植性,控制,独立性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM