Skip to main content

NeoSQLite - NoSQL for SQLite with PyMongo-like API

PyPI Version

NeoSQLite (new + nosqlite) is a pure Python library that provides a schemaless, PyMongo-like wrapper for interacting with SQLite databases. The API is designed to be familiar to those who have worked with PyMongo, providing a simple and intuitive way to work with document-based data in a relational database.

Keywords: NoSQL, NoSQLite, SQLite NoSQL, PyMongo alternative, SQLite document database, Python NoSQL, schemaless SQLite, MongoDB-like SQLite

NeoSQLite: SQLite with a MongoDB Disguise

Features

  • PyMongo-like API: A familiar interface for developers experienced with MongoDB.
  • NX-27017: MongoDB Wire Protocol Server — Use PyMongo with SQLite backend
  • Schemaless Documents: Store flexible JSON-like documents.
  • Lazy Cursor: find() returns a memory-efficient cursor for iterating over results.
  • Raw Batch Support: find_raw_batches() returns raw JSON data in batches for efficient processing.
  • Advanced Indexing: Single-key, compound-key, nested-key indexes, and FTS5 text search.
  • TTL Indexes: expireAfterSeconds expiry with lazy auto-purge and an opt-in background sweeper.
  • ACID Transactions: Full ClientSession API with PyMongo 4.x parity using SQLite SAVEPOINTs.
  • Change Streams: Native SQLite triggers for watch() — no replica set required.
  • Advanced Aggregation: $setWindowFields, $graphLookup, $fill, streaming $facet, and more.
  • Tier-1 SQL Optimization: Dozens of operators translated to native SQL for 10-100x speedup.
  • Native $jsonSchema: Query filtering and write-time validation via SQLite CHECK constraints.
  • Window Functions: Complete MongoDB 5.0+ suite ($rank, $top, $bottom, math operators).
  • MongoDB-compatible ObjectId: Full 12-byte specification with automatic generation.
  • Full GridFS Support: Modern GridFSBucket API plus legacy GridFS compatibility.
  • Binary Data: PyMongo-compatible Binary class with UUID support.
  • AutoVacuum & compact: Reclaim disk space with incremental or full VACUUM.
  • dbStats Command: MongoDB-compatible statistics with accurate index sizes.
  • SQL Translation Caching: 10-30% faster for repeated aggregation pipelines and $expr queries.
  • Configurable Journal Mode: WAL (default), DELETE, MEMORY, and more.
  • Security Hardening: Built-in SQL injection protection via centralized identifier quoting.

See Release Notes for the full history.

Latest Release: v1.17.2

NeoSQLite v1.17.2 is a correctness and PyMongo API parity release resolving gaps surfaced during real-world dogfooding (e.g. against blogging platforms like neo-blogger). It introduces native SQLite FTS5 BM25 text relevance scoring and sorting in find(), PyMongo-compatible multi-field text index creation syntax, fluent chaining methods on GridOutCursor, direct Connection instantiation for GridFSBucket, safe collection counting on GridFS system tables, and expanded unit test coverage reaching 81.18%. Fully backward compatible.

Key Highlights:

  • FTS5 BM25 Text Relevance Scoring & Sorting — find({"$text": {"$search": ...}}) computes true BM25 relevance scores across indexed fields, supports score projection via {"score": {"$meta": "textScore"}}, and enables sorting by [("score", {"$meta": "textScore"})].
  • MongoDB-Style Multi-Field Text Index Definitions — collection.create_index([("field1", "text"), ("field2", "text")]) creates FTS virtual tables across all specified text fields in a single call, matching PyMongo syntax.
  • Fluent GridOutCursor Operations — Added .sort(), .skip(), .limit(), .batch_size(), .to_list(), .clone(), and .rewind() to GridOutCursor for idiomatic cursor chaining on GridFS file searches.
  • Direct Connection Support in GridFSBucket — GridFSBucket(conn) accepts a neosqlite.Connection directly (automatically unwrapping the underlying SQLite database handle) alongside raw database connections (GridFSBucket(conn.db)).
  • Safe Document Counting on GridFS System Collections — Dotted collection access like conn.fs.files.count_documents() maps directly onto relational schema columns without raising no such column: data.
  • Robust Quality Gates & Differential Testing — Achieved 100.0% compatibility across 404 comparison cases against MongoDB 8.2.12, passed 3,034 pytest unit tests with 81.18% code coverage, and verified zero mypy/lint warnings.

For full details, see documents/releases/v1.17.2.md. Previous release highlights are in documents/releases/v1.17.1.md.

Installation

pip install neosqlite

Optional Extras

# Enhanced JSON/JSONB support (only needed if your SQLite lacks JSON functions)
pip install neosqlite[jsonb]

# Memory-constrained processing for large result sets
pip install neosqlite[memory-constrained]

# NX-27017 MongoDB Wire Protocol Server
pip install "neosqlite[nx27017]"          # Core
pip install "neosqlite[nx27017-speed]"    # With uvloop (Linux/macOS)

Quickstart

import neosqlite

with neosqlite.Connection(':memory:') as conn:
    users = conn.users

    # Insert
    users.insert_one({'name': 'Alice', 'age': 30})
    users.insert_many([
        {'name': 'Bob', 'age': 25},
        {'name': 'Charlie', 'age': 35}
    ])

    # Find
    alice = users.find_one({'name': 'Alice'})
    for user in users.find():
        print(user)

    # Update
    users.update_one({'name': 'Alice'}, {'$set': {'age': 31}})

    # Delete & Count
    result = users.delete_many({'age': {'$gt': 30}})
    print(f"Remaining: {users.count_documents({})}")

Drop-in Replacement for PyMongo

1. Direct API (No MongoDB)

import neosqlite
client = neosqlite.Connection('mydatabase.db')
collection = client.mycollection
collection.insert_one({"name": "test"})

2. Wire Protocol (NX-27017) — Zero Code Changes

# Start server
nx-27017 --db ./myapp.db
# Then use PyMongo normally — no code changes!
from pymongo import MongoClient
client = MongoClient('mongodb://localhost:27017/')
collection = client.mydatabase.mycollection
collection.insert_one({"name": "test"})  # Works!

PyMongo Compatibility

Metric Result
Total Tests 381
Passed 363
Skipped 18 (architectural differences)
Failed 0
Compatibility 100%

Skipped tests are due to MongoDB requiring a replica set (change streams, transactions) or NeoSQLite extensions ($log2, $contains). All comparable APIs pass. Tested against MongoDB 8.x (mongo:8.2.12 pinned container image).

Run the comparison yourself: ./scripts/run-api-comparison.sh

_id Field Behavior

NeoSQLite uses a strict MongoDB-compatible _id column:

  • Integer _id values are stored and queried in the dedicated _id column — not redirected to the auto-increment id rowid.
  • String _id values are kept verbatim (e.g., "5" is a string, not converted to integer 5).
  • Auto-generated _id produces MongoDB-compatible 12-byte ObjectIds stored in the _id column.
  • Legacy collections (created before the _id column existed) fall back to the id column via an automatic resolver.
  • Range queries ($gt, $lt, etc.) on _id use Python evaluation to preserve correct cross-type comparison semantics (MongoDB BSON ordering).

Key APIs

Indexes

# Single-key, compound, nested
users.create_index('age')
users.create_index([('name', neosqlite.ASCENDING), ('age', neosqlite.DESCENDING)])
users.create_index('profile.followers')

# FTS5 text search
users.create_search_index('bio')

Query Operators

$eq, $gt, $gte, $lt, $lte, $ne, $in, $nin, $and, $or, $not, $nor, $exists, $type, $regex, $elemMatch, $size, $mod, $bitsAllSet, $bitsAllClear, $bitsAnySet, $bitsAnyClear, $text (FTS5), $jsonSchema, and more.

Aggregation Stages

$match, $project, $group, $sort, $skip, $limit, $unwind, $lookup, $facet, $bucket, $bucketAuto, $sample, $merge, $setWindowFields, $graphLookup, $fill, $densify, $unionWith, $replaceRoot, $replaceWith, $unset, $count, $redact, $addFields, $switch.

Transactions

with client.start_session() as session:
    with session.start_transaction():
        users.insert_one({"name": "Alice"}, session=session)
        orders.insert_one({"user": "Alice"}, session=session)
    # Commits on success, rolls back on exception

Change Streams

# Native SQLite triggers — no replica set needed
stream = collection.watch()
for change in stream:
    print(change)

Journal Mode

from neosqlite import Connection, JournalMode

db = Connection("app.db", journal_mode=JournalMode.WAL)  # Default
Mode Use Case
WAL Best concurrency (default)
DELETE Single-file distribution
MEMORY Maximum speed, no crash recovery

Documentation

Topic Link
Knowledge Base / Docs documents/
Release Notes documents/releases/
GridFS documents/gridfs.md
Text Search documents/text-search.md
Aggregation Optimization documents/aggregation-pipeline-optimization.md
NX-27017 Server packages/nx_27017/README.md
API Comparison examples/api_comparison/README.md

Contributing

Clone the repository:

git clone https://github.com/cwt/neosqlite.git
cd neosqlite

Create and activate a virtual environment:

python3 -m venv .venv
source .venv/bin/activate

Then run the test script, which installs all required dependencies automatically:

./scripts/runtest.sh

Shell Script Compatibility

All shell scripts in this project target bash 3.2+ for compatibility with macOS, which still ships with bash 3.2.x. Please ensure any contributions to shell scripts remain compatible.

Contribution and License

This project was originally developed as shaunduncan/nosqlite and was later forked as plutec/nosqlite before becoming NeoSQLite. It is now maintained by Chaiwat Suttipongsakul and is licensed under the MIT license.

Contributions are highly encouraged. If you find a bug, have an enhancement in mind, or want to suggest a new feature, please feel free to open an issue or submit a pull request.

Metadata

Release files for neosqlite 1.17.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for neosqlite 1.17.2
File Size Uploaded
neosqlite-1.17.2.tar.gz 309.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for neosqlite 1.17.2
File Interpreter ABI Platform
neosqlite-1.17.2-py3-none-any.whl Python 3 none any Details

Total release size: 679.4 kB

Release files / neosqlite-1.17.2.tar.gz

Download URL neosqlite-1.17.2.tar.gz
Size 309.5 kB
Tags Source
SHA-256 checksum
How to use checksums
8dc38a911f0541a9566e51d53e8cad540eb7b0d51334dcc76b8d5fbf8cb5c99e
BLAKE2b-256 checksum
How to use checksums
2d8bf1efa263f1cfbb703a87941e19a74ed34f77d47b14d029f2d4ac39a338c1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.4.1 CPython/3.14.8 Linux/7.2.10-200.fc44.x86_64

Release files / neosqlite-1.17.2-py3-none-any.whl

Download URL neosqlite-1.17.2-py3-none-any.whl
Size 369.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c8e79ae64b015a9753801cdee9d0cac95b5065bb18f29983c8fde15e97c373b4
BLAKE2b-256 checksum
How to use checksums
0331229342941753ce209f231a71fd7b6b63a8a3b9e0e334b7ad77222f781157
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.4.1 CPython/3.14.8 Linux/7.2.10-200.fc44.x86_64

Release history Release notifications | RSS feed

This release

1.17.2 This release

2 release files

1.17.0

2 release files

1.16.3

2 release files

1.16.2

2 release files

1.16.1

2 release files

1.16.0

2 release files

1.15.1

2 release files

1.15.0

2 release files

1.14.9

2 release files

1.14.8

2 release files

1.14.7

2 release files

1.14.6

2 release files

1.14.5

2 release files

1.14.4

2 release files

1.14.3

2 release files

1.13.9

2 release files

1.13.8

2 release files

1.13.7

2 release files

1.13.6

2 release files

1.13.5

2 release files

1.13.4

2 release files

1.13.3

2 release files

1.13.2

2 release files

1.13.1

2 release files

1.13.0

2 release files

1.12.1

2 release files

1.12.0

2 release files

1.11.0

2 release files

1.10.1

2 release files

1.10.0

2 release files

1.9.2

2 release files

1.9.1

2 release files

1.9.0

2 release files

1.8.0

2 release files

1.7.0

2 release files

1.6.1

2 release files

1.6.0

2 release files

1.5.0

2 release files

1.4.0

2 release files

1.3.2

2 release files

1.3.1

2 release files

1.3.0

2 release files

1.2.3

2 release files

1.2.2

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.3

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.7

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.3

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page