• Stars
    star
    580
  • Rank 77,010 (Top 2 %)
  • Language
    Python
  • License
    BSD 3-Clause "New...
  • Created over 6 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Monty, Mongo tinified. MongoDB implemented in Python !

drawing

Python package Version PyPi downloads

Monty, Mongo tinified. MongoDB implemented in Python!

Inspired by TinyDB and it's extension TinyMongo

What is it?

A pure Python-implemented database that looks and works like MongoDB.

>>> from montydb import MontyClient

>>> col = MontyClient(":memory:").db.test
>>> col.insert_many( [{"stock": "A", "qty": 6}, {"stock": "A", "qty": 2}] )
>>> cur = col.find( {"stock": "A", "qty": {"$gt": 4}} )
>>> next(cur)
{'_id': ObjectId('5ad34e537e8dd45d9c61a456'), 'stock': 'A', 'qty': 6}

Most of the CRUD operators have been implemented. You can visit issue #14 to see the full list.

This project is tested against:

  • MongoDB: 3.6, 4.0, 4.2 (4.4 on the way💦)
  • Python: 3.7, 3.8, 3.9, 3.10, 3.11

Install

pip install montydb
  • optional, to use real bson in operation (pymongo will be installed) For minimum requirements, montydb ships with it's own fork of ObjectId in montydb.types, so you may ignore this option if ObjectId is all you need from bson

    pip install montydb[bson]
  • optional, to use lightning memory-mapped db as storage engine

    pip install montydb[lmdb]

Storage

🦄 Available storage engines:

  • in-memory
  • flat-file
  • sqlite
  • lmdb (lightning memory-mapped db)

Depending on which one you use, you may have to configure the storage engine before you start.

⚠️

The configuration process only required on repository creation or modification. And, one repository (the parent level of databases) can only assign one storage engine.

To configure a storage, see flat-file storage for example:

from montydb import set_storage, MontyClient


set_storage(
    # general settings
    
    repository="/db/repo",  # dir path for database to live on disk, default is {cwd}
    storage="flatfile",     # storage name, default "flatfile"
    mongo_version="4.0",    # try matching behavior with this mongodb version
    use_bson=False,         # default None, and will import pymongo's bson if None or True

    # any other kwargs are storage engine settings.
    
    cache_modified=10,       # the only setting that flat-file have
)

# ready to go

Once that done, there should be a file named monty.storage.cfg saved in your db repository path. It would be /db/repo for the above examples.

Configuration

Now let's moving on to each storage engine's config settings.

🌟 In-Memory

memory storage does not need nor have any configuration, nothing saved to disk.

from montydb import MontyClient


client = MontyClient(":memory:")

# ready to go

🔰 Flat-File

flatfile is the default on-disk storage engine.

from montydb import set_storage, MontyClient


set_storage("/db/repo", cache_modified=5)  # optional step
client = MontyClient("/db/repo")  # use current working dir if no path given

# ready to go

FlatFile config:

[flatfile]
cache_modified: 0  # how many document CRUD cached before flush to disk.

💎 SQLite

sqlite is NOT the default on-disk storage, need configuration first before getting client.

Pre-existing sqlite storage file which saved by montydb<=1.3.0 is not read/writeable after montydb==2.0.0.

from montydb import set_storage, MontyClient


set_storage("/db/repo", storage="sqlite")  # required, to set sqlite as engine
client = MontyClient("/db/repo")

# ready to go

SQLite config:

[sqlite]
journal_mode = WAL
check_same_thread =   # Leave it empty as False, or any value will be True

Or,

repo = "path_to/repo"
set_storage(
    repository=repo,
    storage="sqlite",
    use_bson=True,
    # sqlite pragma
    journal_mode="WAL",
    # sqlite connection option
    check_same_thread=False,
)
client = MontyClient(repo)
...

SQLite write concern:

client = MontyClient("/db/repo",
                     synchronous=1,
                     automatic_index=False,
                     busy_timeout=5000)

🚀 LMDB (Lightning Memory-Mapped Database)

lightning is NOT the default on-disk storage, need configuration first before get client.

Newly implemented.

from montydb import set_storage, MontyClient


set_storage("/db/repo", storage="lightning")  # required, to set lightning as engine
client = MontyClient("/db/repo")

# ready to go

LMDB config:

[lightning]
map_size: 10485760  # Maximum size database may grow to.

URI

Optionally, You could prefix the repository path with montydb URI scheme.

client = MontyClient("montydb:///db/repo")

Utilities

Pymongo bson may required.

  • montyimport

    Imports content from an Extended JSON file into a MontyCollection instance. The JSON file could be generated from montyexport or mongoexport.

    from montydb import open_repo, utils
    
    
    with open_repo("foo/bar"):
        utils.montyimport("db", "col", "/path/dump.json")
  • montyexport

    Produces a JSON export of data stored in a MontyCollection instance. The JSON file could be loaded by montyimport or mongoimport.

    from montydb import open_repo, utils
    
    
    with open_repo("foo/bar"):
        utils.montyexport("db", "col", "/data/dump.json")
  • montyrestore

    Loads a binary database dump into a MontyCollection instance. The BSON file could be generated from montydump or mongodump.

    from montydb import open_repo, utils
    
    
    with open_repo("foo/bar"):
        utils.montyrestore("db", "col", "/path/dump.bson")
  • montydump

    Creates a binary export from a MontyCollection instance. The BSON file could be loaded by montyrestore or mongorestore.

    from montydb import open_repo, utils
    
    
    with open_repo("foo/bar"):
        utils.montydump("db", "col", "/data/dump.bson")
  • MongoQueryRecorder

    Record MongoDB query results in a period of time. Requires to access database profiler.

    This works via filtering the database profile data and reproduce the queries of find and distinct commands.

    from pymongo import MongoClient
    from montydb.utils import MongoQueryRecorder
    
    client = MongoClient()
    recorder = MongoQueryRecorder(client["mydb"])
    recorder.start()
    
    # Make some queries or run the App...
    recorder.stop()
    recorder.extract()
    {<collection_1>: [<doc_1>, <doc_2>, ...], ...}
  • MontyList

    Experimental, a subclass of list, combined the common CRUD methods from Mongo's Collection and Cursor.

    from montydb.utils import MontyList
    
    mtl = MontyList([1, 2, {"a": 1}, {"a": 5}, {"a": 8}])
    mtl.find({"a": {"$gt": 3}})
    MontyList([{'a': 5}, {'a': 8}])

Development

montydb uses Poetry to make it easy manage dependencies and set up the development environment.

Initial setup

After cloning the repository, you need to run the following commands to set up the development environment:

make install

This will create a virtual environment and download the required dependencies.

updating dependencies

To keep dependencies updated after git operations such as local updates or merging changes into local dev branch

make update

Makefile

A makefile is used to simplify common operations such as updating, testing, and deploying etc.

make or make help

install                        install all dependencies locally
update                         update project dependencies locally (run after git update)
ci                             Run all checks (codespell, lint, bandit, test)
test                           Run tests
lint                           Run linting with flake8
codespell                      Find typos with codespell
bandit                         Run static security analysis with bandit
build                          Build project using poetry
clean                          Clean project

Run mongo docker image

Most of our tests compare montydb CRUD results against real mongodb instance, therefore we must have a running mongodb before testing.

For example, if we want to test against mongo 4.4:

docker run --name monty-4.4 -p 30044:27017 -d mongo:4.4

Tests

poetry run pytest --storage {storage engin name} --mongodb {mongo instance url} [--use-bson]

Example:

poetry run pytest --storage memory --mongodb localhost:30044 --use-bson

Why did I make this?

Mainly for personal skill practicing and fun.

I work in the VFX industry and some of my production needs (mostly edge-case) requires to run in a limited environment (e.g. outsourced render farms), which may have problem to run or connect a MongoDB instance. And I found this project really helps.


This project is supported by JetBrains

drawing    drawing

More Repositories

1

NodeSticker

Put custom icon on any Maya node for display in the GUI, no plug-in needed
Python
49
star
2

sweet

Rez suite composing GUI
Python
26
star
3

MS_XGenHub

Inhouse Maya XGen legacy simple version control tool
Python
24
star
4

nuke-knobby

Parsing back and forth between dict and node knobs in Nuke
Python
21
star
5

rezup

Rez launching environment manager
Python
17
star
6

maya-diff

An ID renew logic for modification tracking in Maya pipeline
Python
17
star
7

rez-deliver

Rez CLI/GUI tool for installing packages from developer package repositories.
Python
12
star
8

Domino_MayaRenderingTool

A python script for rendering in Maya renderView by frame.
Python
11
star
9

avalon-sftpc

Avalon SFTP Client, for uploading Avalon workfile or representation to remote site via SFTP
Python
10
star
10

PixarUSD-Sublime

Pixar - Universal Scene Description (.USD) Syntax highlight for Sublime Text
7
star
11

reveries-config

Reveries - Pipeline Configuration of Avalon
Python
7
star
12

rez-packages

Python
7
star
13

rez-ghostwriter

Rez developer package ghostwriter for unit-test
Python
7
star
14

MS_SBS2MAYA

Auto build PBR shading network with textures exported from Substance Designer
Python
6
star
15

get-maya-devkit

A Maya devkit download script
Python
5
star
16

rez-miniconda

Ship Python to Rez with Miniconda
Python
5
star
17

qoverview

Vertical space extended QTreeView
Python
4
star
18

MS_TransShader

A shader transfer tool for maya.
Python
4
star
19

MS_GeoCache

Moonshine Maya Geometry Cache Tool
Mathematica
3
star
20

rezbefoo

A proof of concept for demoing how Rez's application type plugin can be used.
Python
2
star
21

MS_Research

Autodesk Maya Pipeline Tools Research for MoonShine@TW
Python
2
star
22

pyblish-plot

A tool for visualize dict data flow in Pyblish plugins from abstract syntax trees.
Python
2
star
23

rez-ozark

Python
1
star
24

MS_SceneHub

Moonshine Maya File Path Tracker
Python
1
star
25

mousetrap

Trap your mouse in blender text input area.
Python
1
star
26

docker-blender

Dockerfile for building blender
Dockerfile
1
star
27

Qt.rez

A Rez package that works as shim around all Qt binding packages.
Python
1
star
28

MS_AniRemap

Maya Remap Animation Between Rigs
Python
1
star
29

pyblish-topic-collection

1
star
30

repo2pdf

Convert entire repository into PDF files and print your code on paper.
Python
1
star