Skip to main content

A dict-like SQLite wrapper with APSW for instant persistence and memory caching

Project description

NyanSQLite

PyPI version Python versions License: MIT Downloads Tests

Pythonic SQLite with Pydantic models, Django-like queries, and FTS5 full-text search.

English | 日本語


日本語

NyanSQLiteは、Pydanticモデルをそのままデータベーススキーマとして利用できる、型安全で高性能なSQLiteラッパーです。
複雑なSQLを書くことなく、Pythonの型ヒントと直感的なクエリでデータを管理できます。

🚀 主な特徴

機能 説明
Pydanticベースのスキーマ 型ヒントで自動バリデーション、JSON変換も透過的
Djangoライクなクエリ __gte, __in, __like など直感的なフィルタリング
FTS5全文検索 テキストデータから高速に検索結果を取得
自動インデックス管理 Indexed[T] アノテーションで B-tree インデックスを自動構築
複雑な型を透過的に処理 dict や list を JSON で保存、自動で Python オブジェクトに戻す
パフォーマンス最適化 WAL モード、バッチ処理による高速化

📦 インストール

pip install nyansqlite

Pydantic v2が必須です:

pip install "pydantic>=2.0"

⚡ 5分クイックスタート

from pydantic import BaseModel
from nyansqlite import NyanSQLite, Indexed, Searchable

# 1️⃣ スキーマ定義(型ヒント+Pydantic)
class Article(BaseModel):
    id: int                      # idフィールドが自動的に主キーになる
    author: Indexed[str]         # インデックス付きカラム
    title: Searchable[str]       # 全文検索対象
    body: Searchable[str]        # 全文検索対象
    views: int = 0

# 2️⃣ DB初期化&テーブル作成
db = NyanSQLite("blog.db")
db.register(Article)

# 3️⃣ データ挿入
db.insert(Article(
    id=1,
    author="neko",
    title="SQLiteを使いこなそう",
    body="NyanSQLiteで簡単にデータ管理ができます。"
))

# 4️⃣ クエリ実行(Django風)
articles = db.query(Article, author="neko", views__gte=0, order_by="id", desc=True)

# 5️⃣ 全文検索(FTS5)
results = db.search(Article, "SQLite")
for hit in results:
    print(f"✨ {hit.title}")

db.close()

🔍 クエリ演算子リファレンス

# 完全一致
db.query(Article, author="neko")

# 演算子フィルタ
db.query(Article, 
    views__gt=10,           # >
    views__gte=10,          # >=
    views__lt=100,          # <
    views__lte=100,         # <=
    views__ne=50,           # !=
)

# 文字列フィルタ
db.query(Article,
    title__like="%Python%", # LIKE検索
)

# IN句
db.query(Article,
    id__in=[1, 2, 3],
)

# NULL チェック
db.query(Article,
    author__is_null=False,
)

🎯 実装例:ゲームのプレイヤーシステム

from datetime import datetime
from pydantic import BaseModel

class Player(BaseModel):
    player_id: int                    # 主キー
    username: Indexed[str]            # ユーザー名でインデックス
    level: Indexed[int]               # レベルでインデックス
    score: int = 0
    created_at: datetime

db = NyanSQLite("game.db")
db.register(Player)

# バッチ登録(大量データが高速)
players = [
    Player(player_id=i, username=f"player_{i}", level=i%50, created_at=datetime.now())
    for i in range(1, 1001)
]
db.insert_many(players)

# ランキング取得
top_players = db.query(Player, order_by="score", desc=True, limit=10)

# 条件付き検索&更新
high_level = db.query(Player, level__gte=40, limit=100)
mid_level = db.query(Player, "level > 10", "level < 40") # 文字列形式のフィルタ
db.update(Player, where={"player_id": 1}, score=9999)

# 数を数える
player_count = db.count(Player)
active_count = db.count(Player, level__gte=30)
pro_count = db.count(Player, "level > 40")  # 文字列形式

📊 パフォーマンス

NyanSQLiteは以下の最適化を実装しています:

  • WAL モード: 読み書き同時実行性の向上
  • トランザクション: insert_many() はデフォルトでトランザクション内で実行
  • パラメータ化クエリ: SQL インジェクション対策も兼ねた安全性
# 10万件をわずか0秒台で挿入(バッチ処理)
import time
players = [Player(player_id=i, ...) for i in range(100000)]
start = time.time()
db.insert_many(players)
print(f"Inserted in {time.time() - start:.4f}s")  # 例: 0.3456s

🛠️ 高度な機能

複合インデックス

from nyansqlite import CompositeIndex

class Order(BaseModel):
    __nyan_indexes__ = [
        CompositeIndex("user_id", "created_at"),
        CompositeIndex("product_id", "status", unique=True),
    ]
    id: int
    user_id: int
    product_id: int
    created_at: datetime
    status: str

主キーのカスタマイズ

フィールド名が id でない場合:

class User(BaseModel):
    __nyan_primary_key__ = "user_id"
    user_id: int
    email: str
    name: str

コンテキストマネージャー

with NyanSQLite("app.db") as db:
    db.register(Article)
    db.insert(Article(...))
    # 自動的にcloseされる

🧹 メンテナンス

# インデックスの再構築
db.rebuild_fts(Article)

# データベース最適化(ファイルサイズを縮小)
db.vacuum()

# 存在確認
if db.exists(Article, id=1):
    print("Found!")

# 部分取得(カラムを指定)
titles = db.select(Article, ["title", "author"], views__gte=100)
recent_titles = db.select(Article, ["title"], "views > 10", "id > 100")

🚨 型モデルのベストプラクティス

from pydantic import ConfigDict

class Article(BaseModel):
    # Pydantic v2の設定
    model_config = ConfigDict(
        arbitrary_types_allowed=True,  # 複雑な型をサポート
        validate_assignment=True,
    )
    
    id: int
    # ... その他フィールド

English

NyanSQLite is a type-safe, high-performance SQLite wrapper that transforms Pydantic models directly into database schemas. Write minimal SQL while leveraging the power of FTS5 full-text search and Django-inspired query syntax.

🚀 Features

Feature Benefit
Pydantic Integration Type-safe validation and automatic JSON serialization
Django-like Queries __gte, __in, __like and more—no SQL needed
FTS5 Search Lightning-fast full-text search on Searchable[str] fields
Auto-Indexing Create B-tree indexes with Indexed[T] annotations
Complex Types Transparent handling of dict, list, and custom types
Performance Optimized WAL mode, batch inserts, parameterized queries

📦 Installation

pip install nyansqlite

Requires Python 3.9+ and Pydantic 2.0+.

⚡ Quick Start

from pydantic import BaseModel
from nyansqlite import NyanSQLite, Indexed, Searchable

class Post(BaseModel):
    id: int
    title: Searchable[str]
    author: Indexed[str]
    views: int = 0

db = NyanSQLite(":memory:")
db.register(Post)

# Insert
db.insert(Post(id=1, title="Hello SQLite", author="neko"))

# Query
posts = db.query(Post, author="neko", views__gte=0)

# Full-text search
results = db.search(Post, "SQLite")

db.close()

📚 API Reference

Core Methods:

  • register(model) – Introspect model and create table
  • insert(obj) – Insert a single record
  • insert_many(objs) – Bulk insert with transaction
  • query(**kwargs) – SELECT with filters, ordering, pagination
  • search(query, limit) – FTS5 full-text search
  • get(**kwargs) – Fetch one record or None
  • update(where, **fields) – Partial UPDATE
  • delete(**kwargs) – Conditional DELETE
  • count(**kwargs) – COUNT rows matching condition
  • exists(**kwargs) – Check if any row matches
  • select(fields, **kwargs) – Fetch specific columns as dicts
  • vacuum() – Optimize database file
  • close() – Close connection

🔗 Resources


License

MIT License – see LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nyansqlite-1.0.0.tar.gz (24.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nyansqlite-1.0.0-py3-none-any.whl (20.1 kB view details)

Uploaded Python 3

File details

Details for the file nyansqlite-1.0.0.tar.gz.

File metadata

  • Download URL: nyansqlite-1.0.0.tar.gz
  • Upload date:
  • Size: 24.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for nyansqlite-1.0.0.tar.gz
Algorithm Hash digest
SHA256 205bbe6a0465633094063eaf959eb61753d852223d229b76059d0ff959b4b36e
MD5 5c09107916f6d0eec3ac5b291864ef2f
BLAKE2b-256 e9fa3cc26b3fb253984af31e428a9ac5b9d4782cbf6c6760709acff7ec4236eb

See more details on using hashes here.

Provenance

The following attestation bundles were made for nyansqlite-1.0.0.tar.gz:

Publisher: ci.yml on disnana/NyanSQLite

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nyansqlite-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: nyansqlite-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 20.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for nyansqlite-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bafb68f8447557db40247daa57abe692a414b704c1781517c703a6bf1791455a
MD5 cd89797125ffc8704f6216316beb6690
BLAKE2b-256 820112eb45a0d2fad20360035645b9fb3c3f16e064da4fd667852baba5e67705

See more details on using hashes here.

Provenance

The following attestation bundles were made for nyansqlite-1.0.0-py3-none-any.whl:

Publisher: ci.yml on disnana/NyanSQLite

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page