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.
  • 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 CHANGELOG.md for the full history.

Latest Release: v1.15.0

NeoSQLite v1.15.0 is a major correctness and parity release resolving all 86 findings from a deep code audit, plus 16 new SQL-tier expression converters, Tier-1 $group activation, and full body-level type checking.

Key Fixes:

  • Translation Cache Correctness — Cache keys include literal values; hits return exact parameters. Fixes silently wrong results on repeated aggregation pipelines.
  • MongoDB Null Semantics — {f: null} matches null-or-missing; $ne matches absent fields, across all tiers.
  • GridFS Integrity — Chunk orphaning fixed; unique chunk index; aborted uploads roll back; corruption raises CorruptGridFile.
  • Aggregation Tier Activation — Tier-1 $group/$bucket/$bucketAuto now run in the fast SQL tier.
  • Typed Rollout — check_untyped_defs enabled: every function body in neosqlite/ is type-checked.

For full details, see documents/releases/v1.15.0.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 379
Passed 361
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.

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
Release Notes documents/releases/
Changelog CHANGELOG.md
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.15.1

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.15.1
File Size Uploaded
neosqlite-1.15.1.tar.gz 289.1 kB Details

Built distribution (wheel)

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

Total release size: 639.1 kB

Release files / neosqlite-1.15.1.tar.gz

Download URL neosqlite-1.15.1.tar.gz
Size 289.1 kB
Tags Source
SHA-256 checksum
How to use checksums
2caf660ed1d9f1413270a7079003a7a585b1a0fa13b88fdfb165d8afd3c8fe10
BLAKE2b-256 checksum
How to use checksums
d46191817481dd6ae1d3600da9cfce328479eed2ebc26b4cd96f53891f73a774
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.4.1 CPython/3.14.7 Linux/7.1.8-200.fc44.x86_64

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

Download URL neosqlite-1.15.1-py3-none-any.whl
Size 350.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2c4fccfa6af81fd0a8d216838c4954d50fee6fd69fd7f67c6b6ac81d1408451b
BLAKE2b-256 checksum
How to use checksums
0ad26489973e95a8500c0470a9f2b8a05b7a25c37de6124a655965131e1aeec1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.4.1 CPython/3.14.7 Linux/7.1.8-200.fc44.x86_64

Release history Release notifications | RSS feed

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

This release

1.15.1 This release

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