A simple wrapper to make a flat file drop in raplacement for mongodb out of TinyDB

Overview

Gitpod Ready-to-Code

logo

Build Status

Purpose

A simple wrapper to make a drop in replacement for mongodb out of tinydb. This module is an attempt to add an interface familiar to those currently using pymongo.

Status

Unit testing is currently being worked on and functionality is being added to the library. Current coverage is 93%. Current builds tested on Python versions 2.7 and 3.3+.

Installation

The latest stable release can be installed via pip install tinymongo.

The library is currently under rapid development and a more recent version may be desired.

In this case, simply clone this repository, navigate to the root project directory, and pip install -e .

or use pip install -e git+https://github.com/schapman1974/tinymongo.git#egg=tinymongo

This is a pure python distribution and - thus - should require no external compilers or tools besides those contained within Python itself.

Examples

The quick start is shown below. For a more detailed look at tinymongo, take a look at demo.py within the repository.

    from tinymongo import TinyMongoClient

    # you can include a folder name or absolute path
    # as a parameter if not it will default to "tinydb"
    connection = TinyMongoClient()

    # either creates a new database file or accesses an existing one named `my_tiny_database`
    db = connection.my_tiny_database

    # either creates a new collection or accesses an existing one named `users`
    collection = db.users

    # insert data adds a new record returns _id
    record_id = collection.insert_one({"username": "admin", "password": "admin", "module":"somemodule"}).inserted_id
    user_info = collection.find_one({"_id": record_id})  # returns the record inserted

    # you can also use it directly
    db.users.insert_one({"username": "admin"})

    # returns a list of all users of 'module'
    users = db.users.find({'module': 'module'})

    #update data returns True if successful and False if unsuccessful
    upd = db.users.update_one({"username": "admin"}, {"$set": {"module":"someothermodule"}})

    # Sorting users by its username DESC
    # omitting `filter` returns all records
    db.users.find(sort=[('username', -1)])

    # Pagination of the results
    # Getting the first 20 records
    db.users.find(sort=[('username', -1)], skip=0, limit=20)
    # Getting next 20 records
    db.users.find(sort=[('username', -1)], skip=20, limit=20)

    # Getting the total of records
    db.users.count()

Custom Storages and Serializers

HINT: Learn more about TinyDB storages and Serializers in documentation

Custom Storages

You have to subclass TinyMongoClient and provide custom storages like CachingMiddleware or other available TinyDB Extension.

Caching Middleware

    from tinymongo import TinyMongoClient
    from tinydb.storages import JSONStorage
    from tinydb.middlewares import CachingMiddleware

    class CachedClient(TinyMongoClient):
        """This client has cache"""
        @property
        def _storage(self):
            return CachingMiddleware(JSONStorage)

    connection = CachedClient('/path/to/folder')

HINT: You can nest middlewares: FirstMiddleware(SecondMiddleware(JSONStorage))

Serializers

To convert your data to a format that is writable to disk TinyDB uses the Python JSON module by default. It's great when only simple data types are involved but it cannot handle more complex data types like custom classes.

To support serialization of complex types you can write your own serializers using the tinydb-serialization extension.

First you need to install it pip install tinydb-serialization

Handling datetime objects

You can create a serializer for the python datetime using the following snippet:

    from datetime import datetime
    from tinydb_serialization import Serializer

    class DatetimeSerializer(Serializer):
        OBJ_CLASS = datetime

        def __init__(self, format='%Y-%m-%dT%H:%M:%S', *args, **kwargs):
            super(DatetimeSerializer, self).__init__(*args, **kwargs)
            self._format = format

        def encode(self, obj):
            return obj.strftime(self._format)

        def decode(self, s):
            return datetime.strptime(s, self._format)

NOTE: this serializer is available in tinymongo.serializers.DateTimeSerializer

Now you have to subclass TinyMongoClient and provide customs storage.

    from tinymongo import TinyMongoClient
    from tinymongo.serializers import DateTimeSerializer
    from tinydb_serialization import SerializationMiddleware


    class CustomClient(TinyMongoClient):
        @property
        def _storage(self):
            serialization = SerializationMiddleware()
            serialization.register_serializer(DateTimeSerializer(), 'TinyDate')
            # register other custom serializers
            return serialization


    connection = CustomClient('/path/to/folder')

Flask-Admin

This extension can work with Flask-Admin which gives a web based administrative panel to your TinyDB. Flask-Admin has features like filtering, search, web forms to perform CRUD (Create, Read, Update, Delete) of the TinyDB records.

You can find the example of Flask-Admin with TinyMongo in Flask-Admin Examples Repository

NOTE: To use Flask-Admin you need to register a DateTimeSerialization as showed in the previous topic.

Contributions

Contributions are welcome! Currently, the most valuable contributions would be:

  • adding test cases
  • adding functionality consistent with pymongo
  • documentation
  • identifying bugs and issues

Future Development

I will also be adding support for gridFS by storing the files somehow and indexing them in a db like mongo currently does

More to come......

License

MIT License

Comments
  • Count example in the docs seems wrong

    Count example in the docs seems wrong

    Hello! Thanks for the great lib ^_^

    I've been testing a bit the examples, and found out that

    # Getting the total of records
    db.users.count()
    

    in the README doesn't work for me, while db.users.find().count() does.

    Am I doing something wrong or is the docs to fix? Thank you, have the greatest day

    opened by pdonorio 6
  • Improve find(); Mongo-like sort(); Include MongoDB in test

    Improve find(); Mongo-like sort(); Include MongoDB in test

    Motive

    To behave more like Mongo.

    Changed

    • add $all
    • find in list
    • add pymongo and MongoDB server in test, for behavior comparing
    • some minor fix or improve
    • Mongo-like sorting, able to read multiple sort_specifiers, and sorting basic types of data

    Still more to do, but I think it's time to merge, since this had made a big change. Thank you :)

    opened by davidlatwe 4
  • Separate prod/test requirements with setup.py

    Separate prod/test requirements with setup.py

    Had issues including tinymongo in projects because of pytest prod requirement. Split prod/test requirements using setup.py.

    • Removes requirements.txt
      • pip install -e . to install for dev
    • Fixed .travis.yml to match new test method
      • python setup.py test to run testpass
      • pip install pytest -U added b/c of python3.3 build on travis only using pytest==2.9.2
    • Added new notes to README to reflect change

    Prod Requirements * tinymongo>=3.2.1 (currently 3.5.0) * tinydb-serialization>=1.0.4 (currently 1.0.4)

    Test Requirements * pytest>=3.2.0 (currently 3.2.2) * py>=1.4.33 (currently 1.4.34)

    opened by lockefox 4
  • Count function on collection should get all documents

    Count function on collection should get all documents

    The tinymongo count function on a collection currently returns a count based on the last query (if I understand the code correctly). The pymongo specs on counting state that count run on a collection returns all of the documents in a collection. We could use len(table) instead to get the length of the whole collection. This would be the same as we do for a cursor (Count Function in Cursor).

    opened by tech4him1 3
  • Invalid TinyDB request in find_one

    Invalid TinyDB request in find_one

    TinyDB get() expects a query instead of a dictionary. Also, when getting multiple matches, it will return a random item (https://tinydb.readthedocs.io/en/latest/usage.html#retrieving-data).

    The solutions that I can see are either to:

    1. Select all elements from the table, then get the first one from the list (this pull request).
    2. Or, we can make a query that selects all, like Query()["_id"].exists(). I don't know if this would return the fist item every time, or a random one.
    opened by tech4him1 3
  • Releases to Pypi?

    Releases to Pypi?

    Hi, I see that https://pypi.python.org/pypi/tinymongo is 0.1.3 and master is 0.1.6 (with new changes going to 0.1.7?)

    When new releases is going to PyPI?

    Thanks

    opened by rochacbruno 2
  • Make it work with Flask-Admin

    Make it work with Flask-Admin

    With my changes this extension can work out of the box with latest version of Flask-Admin

    Example can be found here: https://github.com/rochacbruno/flask-admin/tree/master/examples/tinymongo

    It supports:

    • Filtering
    • Sorting
    • Pagination
    • referencing on forms

    tinymongo_flask_admin

    opened by rochacbruno 2
  • PEP8 compliance, more complete setup.py, improved demo

    PEP8 compliance, more complete setup.py, improved demo

    Greetings,

    I like the tinymongo library idea and the embedded demo. I would like to contribute functionality, but I feel like the project organization and setup could use a bit of love. That is what this pull request is focused on.

    j

    opened by jjonesAtMoog 2
  • count() method for the TinyMongoCollection class

    count() method for the TinyMongoCollection class

    opened by ramuta 1
  • A small problem in README.md

    A small problem in README.md

    Your code: record_id = collection.insert_one({'username': 'admin', 'password': 'hello world'}) user_info = collection.find_one({'_id': record_id})

    But record_id is an <tinymongo.results.InsertOneResult object>

    I read some code. I think it should be record_id = collection.insert_one({'username': 'admin', 'password': 'hello world'}).inserted_id

    Tested in Python 3.6.1.

    opened by g10guang 1
  • Functionally the same, lots of updates

    Functionally the same, lots of updates

    Greetings -

    Without consulting you, I took some liberties with the code. In particular, I assumed that you wished to be up-to-date with the latest thinking as far as the pymongo libraries go.

    This pull request will:

    • create docstrings for several methods
    • add some test framework
    • add functions that are more up-to-date with the current pymongo lib (update_one, update_many, delete_one, delete_many, insert_one, insert_many)
    • queries are now able to accept some '$' values that weren't parsed before, such as '$gt'
    • added lots of 'todo' items within the code in places where I didn't have time to fix it or wasn't sure exactly how to proceed from a technical standpoint or from the author's intent

    I don't believe that I have broken anything, but with the test framework, it should be reasonably easy to add tests to backup the work that has been done up to this point. I would highly encourage that the author add tests to backup the current work so that contributors may know when they have broken something during development.

    I forgot to update the readme, you may want to do that.

    Enjoy!

    j

    opened by jjonesAtMoog 1
  • Updated alernative

    Updated alernative

    This project had a lot of potential but since it's not maintained anymore (e.g. broken with TInyDB 4), https://github.com/davidlatwe/montydb seems very promising

    opened by ishtanzar 1
  • Code from README does not work

    Code from README does not work

    Tries running code from "examples" section, got RecursionError

    from tinymongo import TinyMongoClient
    >>> connection = TinyMongoClient()
    >>> db = connection.my_tiny_database
    Traceback (most recent call last):
      File "<input>", line 1, in <module>
      File "/Users/whatever/my_project/.venv/lib/python3.8/site-packages/tinymongo/tinymongo.py", line 73, in __getattr__
        return TinyMongoDatabase(name, self._foldername, self._storage)
      File "/Users/whatever/my_project/.venv/lib/python3.8/site-packages/tinymongo/tinymongo.py", line 73, in __getattr__
        return TinyMongoDatabase(name, self._foldername, self._storage)
      File "/Users/whatever/my_project/.venv/lib/python3.8/site-packages/tinymongo/tinymongo.py", line 73, in __getattr__
        return TinyMongoDatabase(name, self._foldername, self._storage)
      [Previous line repeated 987 more times]
    RecursionError: maximum recursion depth exceeded
    
    opened by DataGreed 0
  • Update setup.py for exact tinydb dependencies

    Update setup.py for exact tinydb dependencies

    Hi, I've installed tinymongo today and had an error. This is because there are newer versions of tinydb and tinydb_serialization which are not backwards compatible. In order for one to be able to just pip install and use your package, I have updated the dependencies in the setup.py to be fixed version (instead of >=).

    If you want you can accept this pull request.

    Thank you for your repository, it is helpful to me :), Elad Levy.

    opened by LevyvoNet 0
  • Error when loading database file

    Error when loading database file

    When using the example code in Python 3.8 i get this error :

    Traceback (most recent call last):
      File "C:/Users/loicn/backend_db.py", line 7, in <module>
        db = connection.my_tiny_database
      File "C:\Users\loicn\AppData\Local\Programs\Python\Python38\lib\site-packages\tinymongo\tinymongo.py", line 73, in __getattr__
        return TinyMongoDatabase(name, self._foldername, self._storage)
      File "C:\Users\loicn\AppData\Local\Programs\Python\Python38\lib\site-packages\tinymongo\tinymongo.py", line 73, in __getattr__
        return TinyMongoDatabase(name, self._foldername, self._storage)
      File "C:\Users\loicn\AppData\Local\Programs\Python\Python38\lib\site-packages\tinymongo\tinymongo.py", line 73, in __getattr__
        return TinyMongoDatabase(name, self._foldername, self._storage)
      [Previous line repeated 996 more times]
    RecursionError: maximum recursion depth exceeded
    
    Process finished with exit code 1
    
    opened by lnoest 11
  • $unset not implemented

    $unset not implemented

    By the way, I'm a big fan of this project as the noSQL alternative to SQLite project.

    I kept wondering why when I used "$unset" nothing was changed. Then I checked the tests, and then finally drilled into the code and noticed that "$unset" is not implemented.

    Are there any plans for adding this?

    opened by jefmud 0
  • Integration with the ODMs?

    Integration with the ODMs?

    This project looks great. Any idea or plans on allowing it to be the backend for higher level libraries like MongoEngine, uMongo?

    It seems like it might be possible to just replace MongoClient() with TinyMongoClient() in some way and potentially ignore things like create index requests if that isn't supported.

    opened by mikeckennedy 0
Owner
null
A simple password manager I typed with python using MongoDB .

Python with MongoDB A simple python code example using MongoDB. How do i run this code • First of all you need to have a python on your computer. If y

null 31 Dec 6, 2022
PyMongo - the Python driver for MongoDB

PyMongo Info: See the mongo site for more information. See GitHub for the latest source. Documentation: Available at pymongo.readthedocs.io Author: Mi

mongodb 3.7k Jan 8, 2023
Motor - the async Python driver for MongoDB and Tornado or asyncio

Motor Info: Motor is a full-featured, non-blocking MongoDB driver for Python Tornado and asyncio applications. Documentation: Available at motor.readt

mongodb 2.1k Dec 26, 2022
Motor - the async Python driver for MongoDB and Tornado or asyncio

Motor Info: Motor is a full-featured, non-blocking MongoDB driver for Python Tornado and asyncio applications. Documentation: Available at motor.readt

mongodb 1.6k Feb 6, 2021
A Python Object-Document-Mapper for working with MongoDB

MongoEngine Info: MongoEngine is an ORM-like layer on top of PyMongo. Repository: https://github.com/MongoEngine/mongoengine Author: Harry Marr (http:

MongoEngine 3.9k Jan 8, 2023
sync/async MongoDB ODM, yes.

μMongo: sync/async ODM μMongo is a Python MongoDB ODM. It inception comes from two needs: the lack of async ODM and the difficulty to do document (un)

Scille 428 Dec 29, 2022
A Pythonic, object-oriented interface for working with MongoDB.

PyMODM MongoDB has paused the development of PyMODM. If there are any users who want to take over and maintain this project, or if you just have quest

mongodb 345 Dec 25, 2022
Async ODM (Object Document Mapper) for MongoDB based on python type hints

ODMantic Documentation: https://art049.github.io/odmantic/ Asynchronous ODM(Object Document Mapper) for MongoDB based on standard python type hints. I

Arthur Pastel 732 Dec 31, 2022
Micro ODM for MongoDB

Beanie - is an asynchronous ODM for MongoDB, based on Motor and Pydantic. It uses an abstraction over Pydantic models and Motor collections to work wi

Roman 993 Jan 3, 2023
Monty, Mongo tinified. MongoDB implemented in Python !

Monty, Mongo tinified. MongoDB implemented in Python ! Inspired by TinyDB and it's extension TinyMongo. MontyDB is: A tiny version of MongoDB, against

David Lai 522 Jan 1, 2023
Query multiple mongoDB database collections easily

leakscoop Perform queries across multiple MongoDB databases and collections, where the field names and the field content structure in each database ma

bagel 5 Jun 24, 2021
MongoX is an async python ODM for MongoDB which is built on top Motor and Pydantic.

MongoX MongoX is an async python ODM (Object Document Mapper) for MongoDB which is built on top Motor and Pydantic. The main features include: Fully t

Amin Alaee 112 Dec 4, 2022
Implementing basic MongoDB CRUD (Create, Read, Update, Delete) queries, using Python.

MongoDB with Python Implementing basic MongoDB CRUD (Create, Read, Update, Delete) queries, using Python. We can connect to a MongoDB database hosted

MousamSingh 4 Dec 1, 2021
A CRUD and REST api with mongodb atlas.

Movies_api A CRUD and REST api with mongodb atlas. Setup First import all the python dependencies in your virtual environment or globally by the follo

Pratyush Kongalla 0 Nov 9, 2022
A library for python made by me,to make the use of MySQL easier and more pythonic

my_ezql A library for python made by me,to make the use of MySQL easier and more pythonic This library was made by Tony Hasson , a 25 year old student

null 3 Nov 19, 2021
Application which allows you to make PostgreSQL databases with Python

Automate PostgreSQL Databases with Python Application which allows you to make PostgreSQL databases with Python I used the psycopg2 library which is u

Marc-Alistair Coffi 0 Dec 31, 2021
A wrapper around asyncpg for use with sqlalchemy

asyncpgsa A python library wrapper around asyncpg for use with sqlalchemy Backwards incompatibility notice Since this library is still in pre 1.0 worl

Canopy 404 Dec 3, 2022
A wrapper for SQLite and MySQL, Most of the queries wrapped into commands for ease.

Before you proceed, make sure you know Some real SQL, before looking at the code, otherwise you probably won't understand anything. Installation pip i

Refined 4 Jul 30, 2022
Little wrapper around asyncpg for specific experience.

Little wrapper around asyncpg for specific experience.

Nikita Sivakov 3 Nov 15, 2021