Skip to content

非同期サポート (NyanSQLiteAIO)

NyanSQLite v1.1.0 から、asyncio を使用した非同期プログラミングをネイティブにサポートする NyanSQLiteAIO クラスが導入されました。

特徴

NyanSQLiteAIO は、以下の特徴を持っています:

  1. ノンブロッキング I/O: 内部で asyncio.to_thread を使用し、データベース操作をバックグラウンドスレッドで実行することで、イベントループをブロックしません。
  2. スレッドセーフ: 書き込み操作には非同期ロックを使用し、マルチスレッド/非同期環境での安全性を確保しています。
  3. 最適化された読み取り: クエリの実行からデータのパース(Pydantic モデルへの変換)までをバックグラウンドスレッド内で一括して行うことで、コンテキストスイッチのオーバーヘッドを最小限に抑えています。

基本的な使い方

NyanSQLiteAIO は非同期コンテキストマネージャをサポートしており、async with 構文で安全に接続・切断を行えます。

python
import asyncio
from pydantic import BaseModel
from nyansqlite import NyanSQLiteAIO, Indexed

class User(BaseModel):
    id: int
    name: Indexed[str]

async def main():
    # 非同期コンテキストマネージャを使用
    async with NyanSQLiteAIO("app.db") as db:
        db.register(User)
        
        # 非同期挿入
        await db.insert(User(id=1, name="alice"))
        
        # 非同期クエリ
        users = await db.query(User, name="alice")
        if users:
            print(f"Found: {users[0].name}")

        # 一括挿入
        await db.insert_many([
            User(id=i, name=f"user_{i}") for i in range(2, 6)
        ])
        
        # カウント操作
        count = await db.count(User)
        print(f"Total users: {count}")

if __name__ == "__main__":
    asyncio.run(main())

メソッド一覧

NyanSQLite (同期版) とほぼ同じ API を非同期(await 可能)として提供しています:

  • await db.insert(obj)
  • await db.insert_many(objs)
  • await db.query(model, ...)
  • await db.get(model, ...)
  • await db.select(model, fields, ...)
  • await db.search(model, query, ...)
  • await db.update(model, where, ...)
  • await db.delete(model, ...)
  • await db.count(model, ...)
  • await db.exists(model, ...)

パフォーマンスの最適化

v1.1.0 以降、読み取り操作(query, select, search)は特に最適化されています。 従来の loop.run_in_executor を個別に呼び出す方法に比べ、データのフェッチと Python オブジェクトへの変換を同一のスレッド内で連続して行うことで、非同期環境下での高いスループットを実現しています。