Skip to main content

A pymongo helper with methods and classes

Project description

Pymongoose

This is a pymongo helper package, that let you make more complicated actions with your collections. It gives you the possibility to populate between packages without needs of creating an aggregation by yourself. Gives you the basic actions such as find, update and delete, with more simplicity.

Pymongoose came with a Schema class that let you work with more efficiency and organization

First Steps

pip install pymongoose pymongo

Create a model:

models/role.py

import datetime
from pymongoose import methods
from pymongoose.mongo_types import Types, Schema, MongoException, MongoError
from bson import json_util
from bson.objectid import ObjectId


class Role(Schema):
    schema_name = "roles" # Name of the schema that mongo uses
    
    # Attributes
    id = None
    name = None
    action = None

    def __init__(self, **kwargs):
        self.schema = {
            "name": {
                "type": Types.String,
                "required": True
            },
            "actions": [{
                "type": Types.String,
                "required": True
            }]
        }

        super().__init__(self.schema_name, self.schema, kwargs)


    def __str__(self):
        return f"Role: {self.name}, Actions: {self.action}"

Is higly recommended to follow this model for any schema

Mongo Configuration

This mongo configuration is required for pymongoose to work correctly

db.py:

    import os, traceback
    import signal 
    from pymongo import MongoClient
    from pymongoose.methods import set_schemas, get_cursor_length
    from models.role import Role

    MONGO_URI = os.environ.get("MONGO_URI")

    mongo_db = None

    def mongo_init ():
        global mongo_db

        client = MongoClient(MONGO_URI)
        db = client.test
        try:
            # Now schemas can be set in two ways
            
            #-> In a dict mode
            schemas = {
                "roles": Role(empty=True).schema
            }
            set_schemas(db, schemas)

            #-> Or in a list mode

            set_schemas_from_list (db, [Role (empty=True)])


            print("MongoDB Connected!")
        except:
            traceback.print_exc()
            print("Error initializing database")
            exit(1)

    if __name__ == "__main__":
        mongo_init()

Examples:

  • For more model examples check examples/

Insert function:

user = User(
    name="TestA",
    password="test",
    role=role.id
)
id = user.save()

user.save() will throw an exception if a field marked as required in schema is None.

Find function:

users = User.find({})
for user in users:
    user = User.parse(user)

This will return a cursor of elements, which can be parsed into User model for a better management.

Find one function:

user = User.find({}, one=True)
# OR
user = User.find_one ({})

This will return a User element with fields obtained by database, if you prefer a json just add

parse = False

At last of the find statement.

Find by id function:

# this Function will search for "_id" field 
# so id must be a hex24 string or ObjectId
user = User.find_by_id(id)
# for a complete user
user = User.find_by_id(id, select={"name": 1, "username": 1})
# For a custom user

This will return a User element with fields obtained by database, if you prefer a json just add

parse = False

At last of the find statement.

Populate a search:

user = User.find_by_id(id, populate=[
    {
        "path": "role",
        "select": ["name", "actions"],
        "options": ["actions"]
    }
])
# For an extensive populate
# or
user = User.find_by_id(id, populate=["role"])
# For a simple populate

This will return a User element with fields obtained by database

Populate is a really useful tool when we work with difficult or complex models, with pymongoose you wont need to create an extensive aggregation to lookup for elements.

Populate works with simple ids like:

schema = {
    "name": {
        "type": Types.String,
        "required": True
    },
    "role": { # <- Simple field
        "type": Types.ObjectId,
        "ref": "roles"
    }
}

lists:

schema = {
    "name": {
        "type": Types.String,
        "required": True
    },
    "logs": [{ # <- List field
        "type": Types.ObjectId,
        "ref": "logs"
    }]
}

and complex models

schema = {
    "name": {
        "type": Types.String,
        "required": True
    },
    "friends": [{ 
        "friend": {
            "type": Types.ObjectId, # <- Complex list field
            "ref": "friends"
        },
        "frequent": {
            "type": Types.Boolean,
            "default": False
        }
    }]
}

Pymongoose can recursively populate fields like this:

    #menu schema:
    menu_schema = {
        # ...
        "items":[
            {
                "type":Types.ObjectId,
                "ref":"items"
            }
        ],
        # ...
    }

    #item schema:
    item_schema: {
        # ...
        "drink":{
            "type":Types.ObjectId,
            "ref":"drinks"
        },
        "dish":{
            "type":Types.ObjectId,
            "ref":"dishes"
        }
        # ...
    }

    #Populate

    menus = Menu.find({}, populate=[{
        "path": "items",
        "options": ["dish", "drink"]
    }])

    for menu in menus:
        print(menu)

This will return a CursorCommand element

In this example all menus populate each item of their array, at same time element dish and drink are populated, returning a complete array of populated menus with populated items.

Parsed finds:

pymongoose has the ability to parse the return cursor as different types: Available types are - IF AS_DEFAULT(0), will return cursor if one == False, else a dict if parse == False - IF AS_DICT(1), will return a list of dicts if one == False, else as serializable dict - IF AS_STRING(2), will return a parsed list of dicts as str if one == False, else as a str parsed serializable dict

*Note: In case you don't need a serializable dict, left cursor AS_DEFAULT

Update item:

count = User.update({},
            {
                "$set": {
                    "password": "0"
                }
            }, many=True
        ) #many is set to False by default

Delete item:

count = User.delete({}, many=True) #many is set to False by default

Note:

If you are working with vscode I have already created a model snippet to save you a lots of time: https://github.com/Djcharles26/pymongoose/blob/master/pymongoose-snippets.json

For using this you must copy them to your python snippets:

  1. CTRL + SHIFT + P
  2. Configure User snippets
  3. python.json
  4. Copy snippets in blob
  5. Paste them in your user python.json

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

pymongoose-1.3.8.tar.gz (17.3 kB view details)

Uploaded Source

Built Distribution

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

pymongoose-1.3.8-py3-none-any.whl (14.6 kB view details)

Uploaded Python 3

File details

Details for the file pymongoose-1.3.8.tar.gz.

File metadata

  • Download URL: pymongoose-1.3.8.tar.gz
  • Upload date:
  • Size: 17.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.9.19

File hashes

Hashes for pymongoose-1.3.8.tar.gz
Algorithm Hash digest
SHA256 3a2dee0422c16143b496c654ee8ce515f431bdc1855d9629bb66f50eaad9ac66
MD5 658a6782b087feed5d8acbd6b6e4bfe0
BLAKE2b-256 6f9fe661034886b9b89e3c6d0068768a877b819bfd7f05ae1b359f11371dbb9d

See more details on using hashes here.

File details

Details for the file pymongoose-1.3.8-py3-none-any.whl.

File metadata

  • Download URL: pymongoose-1.3.8-py3-none-any.whl
  • Upload date:
  • Size: 14.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.9.19

File hashes

Hashes for pymongoose-1.3.8-py3-none-any.whl
Algorithm Hash digest
SHA256 ce1250e517afe1c0b2d7e3bedf3baccbef3e150e535982a323a2632410f88f87
MD5 79061bb13492fefccc8f54b699871353
BLAKE2b-256 183d83999a4f3d8fe93818a194db3e8f4f3a7377c89764f082dd0ec23c8a08fa

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