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

NeoSQLite v1.14.14 is a security hardening, code quality, and modernization release that patches SQL injection vectors, improves transaction atomicity, and modernizes the codebase for Python 3.8+.

Key Fixes:

  • SQL Injection Hardening — Parameterized load_extension(), PRAGMA whitelist validation, and GridFS identifier quoting.
  • Atomicity Fix — Change Stream _last_id now updated inside BEGIN IMMEDIATE to prevent race conditions.
  • Code Quality — Removed dead code, replaced bare except: pass with logging, fixed $currentDate validation.
  • Python 3.8+ Modernization@cache, walrus operator, slots=True, collections.abc imports.

For full details, see documents/releases/v1.14.14.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.14.tar.gz (261.5 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.14-py3-none-any.whl (297.6 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: neosqlite-1.14.14.tar.gz
  • Upload date:
  • Size: 261.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.4 CPython/3.14.4 Linux/6.19.13-200.fc43.x86_64

File hashes

Hashes for neosqlite-1.14.14.tar.gz
Algorithm Hash digest
SHA256 f5be112e670c747737a0cc77df0cc2cb10a9937b5ca9797c39738bd9db08eb51
MD5 61810a65bf9fc3983ac13950dc38b56d
BLAKE2b-256 0a49656f4b4c2a587b01c53e9b2c1d08011513f32096c3c0f6b18250d49a3275

See more details on using hashes here.

File details

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

File metadata

  • Download URL: neosqlite-1.14.14-py3-none-any.whl
  • Upload date:
  • Size: 297.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.4 CPython/3.14.4 Linux/6.19.13-200.fc43.x86_64

File hashes

Hashes for neosqlite-1.14.14-py3-none-any.whl
Algorithm Hash digest
SHA256 2814c9b9f16f18979c2c9318042165aa97d2a40460c30c2cce8265fb4d0061c9
MD5 9073b7893e79a2cde986125f530d20e9
BLAKE2b-256 a8a7c7b660eff6a65fd58d588bad0578ee842fa50e307c84cd315772aa6fe9cc

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