Skip to main content

NoSQL for SQLite with PyMongo-like API

Project description

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.14.8

NeoSQLite v1.14.8 is a bug fix release that resolves a critical $facet stage failure when JSONB is enabled.

Key Fix: $facet now correctly handles JSONB binary format when extracting documents from temporary tables. Without this fix, pipelines with $unwind + $group sub-pipelines would skip all documents due to UTF-8 decode errors on JSONB binary data.

Key Fixes

  • $facet JSONB Decode Error: Fixed false UnicodeDecodeError when $facet extracts documents from JSONB temporary tables. Documents are now properly extracted using json(data) conversion.

For full details, see documents/releases/v1.14.8.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 386
Passed 368
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

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.

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

neosqlite-1.14.8.tar.gz (258.2 kB view details)

Uploaded Source

Built Distribution

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

neosqlite-1.14.8-py3-none-any.whl (294.2 kB view details)

Uploaded Python 3

File details

Details for the file neosqlite-1.14.8.tar.gz.

File metadata

  • Download URL: neosqlite-1.14.8.tar.gz
  • Upload date:
  • Size: 258.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.3 CPython/3.14.3 Linux/6.19.11-200.fc43.x86_64

File hashes

Hashes for neosqlite-1.14.8.tar.gz
Algorithm Hash digest
SHA256 1ff34b04db05ea1fa14bcedc5da97c9ca5fb6bdc7d1afde57b1754570b144c6e
MD5 e11d261d6201a7694d4402f2a16f610c
BLAKE2b-256 f5c739941b9f70d34416e39c6fabd219d511b6f0659d4aa3ec3a5458c60a0c86

See more details on using hashes here.

File details

Details for the file neosqlite-1.14.8-py3-none-any.whl.

File metadata

  • Download URL: neosqlite-1.14.8-py3-none-any.whl
  • Upload date:
  • Size: 294.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.3 CPython/3.14.3 Linux/6.19.11-200.fc43.x86_64

File hashes

Hashes for neosqlite-1.14.8-py3-none-any.whl
Algorithm Hash digest
SHA256 03556999dc2dfedb1bdc9c728663b394de81ccc9282f38204daf10bb2602b6d1
MD5 3a820be2e9c509e7b472484a7a80a3e4
BLAKE2b-256 299e1cdbc8b46753f33041a297dbfd7fecc177e2087f432467299e90ae3060c4

See more details on using hashes here.

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