Skip to main content

Asynchronous Python ODM for MongoDB based on Motor

Project description

MongODM

MongODM is a simple, lightweight, and asynchronous Object Document Mapper for MongoDB. It uses Pydantic and Motor.

Installation

pip install python-mongodm

Usage

import mongodm
from motor.motor_asyncio import AsyncIOMotorClient

mongodm.set_config(AsyncIOMotorClient('mongodb://localhost:27017'), 'test')


class Entity(mongodm.MongoODMBase):
    __collection_name__ = 'my_entity'
    __protected_attributes__ = {'protected'}  # Writable on first creation, but not on updates

    title: str
    description: str
    protected: str


item = Entity(title='title', description='description', protected='protected')
await item.save()  # Commit in DB
item.dict()  # {'title': 'title', 'description': 'description', 'protected': 'protected', created_at: datetime.datetime(), updated_at: None, deleted_at: None}

db_items = await Entity.get_all()  # List of instances from db
db_items[0].title = 'modification'
await db_items[0].save()
await db_items[0].delete()

# To change multiples attributes simultaneously, pydantic constructor style
new_attributes_dict = {'title': 'edited', 'description': 'edited'}
item.set_attributes(**new_attributes_dict)  

# You can also use the collection getter directly to send a raw query to the database
random_item = await Entity.get_collection().aggregate([{'$sample': {'size': 1}}]).to_list(1)[0]

The default _id field constructor is uuid.uuid4 marshalled to a string. It is possible to change it by setting __id_constructor__ to a callable that returns the desired type.

It will still be casted to a string before being written in the database. If you want this field to be of another type than a string in Mongo, you can set __id_marshaller__ to any type accepted by MongoDB.

The configuration for the database can be set with set_config()
You can enable soft delete by using set_config with soft_delete=True.

mongodm.set_config(AsyncIOMotorClient("mongodb://localhost:27017"), "my_database", soft_delete=True)

Since the whole thing is based on Pydantic, you can use all the features of Pydantic.

from pydantic import Field, validator

class Entity(mongodm.MongoODMBase):
    __collection_name__ = 'my_entity'
    title: str
    description: str
    protected: str = Field(default='protected', description='This is a protected field')

    @validator('title')
    def title_must_contain_space(cls, v):
        if ' ' not in v:
            raise ValueError('must contain a space')
        return v.title()

You can even modify the pydantic config by creating a new class that inherits from MongoODMBase and override the pydantic Config subclass.

class MyBase(mongodm.MongoODMBase):
    class Config(mongodm.MongoODMBase.Config):
        allow_population_by_field_name = True

class Entity(MyBase):
    ...

Encrypted fields

It is possible to encrypt string fields in the database by using the EncryptedStr class. It uses rsa to encrypt the data and store it in the database as a string. MongODM will automatically decrypt the data when it is retrieved from the database. You will need to configure the encryption by using set_encryption_config().

This approach is very opinionated, and is proposed as an alternative if you don't want to use the MongoDB encryption features.

import mongodm

mongodm.set_encryption_config(
    public_key='YOUR_RSA_PUBLIC_KEY_VALUE',
    private_key='YOUR_RSA_PRIVATE_KEY_VALUE'
)

Hooks

You can use hooks to execute code before or after a variety of events. The following hooks are available:

  • before_create(): Before the object is created in the database.
  • after_create(): After the object is created in the database.
  • before_save(): Before the object is saved in the database, called both during creation and update operations.
  • after_save(): After the object is saved in the database, called both during creation and update operations.
  • before_update(payload): Before the object is updated in the database. You can access the payload with the payload argument, and you MUST return it.
  • after_update(): After the object is updated in the database
  • after_find(): After the object is found in the database
  • before_delete(): Before the object is deleted in the database
  • after_delete(): After the object is deleted in the database
  • after_soft_delete() (only if soft delete is enabled)
  • after_hard_delete() (only if soft delete is disabled)

All the hooks must be declared as async functions. To define one you have to override the method on your class with the same signature as the hook you want to use.

def before_create(self):
    self.created_at = datetime.now().isoformat()

# You must use the same method signature and return it at the end
def before_update(self, payload):
    payload['updated_at'] = datetime.now().isoformat()
    return payload

Contributing

Contributions are welcome! Please open an issue or a pull request. We are looking for reviews and feedback on the basic design of the library.

License

MIT

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

python_mongodm-0.1.6.tar.gz (9.1 kB view details)

Uploaded Source

Built Distribution

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

python_mongodm-0.1.6-py3-none-any.whl (8.1 kB view details)

Uploaded Python 3

File details

Details for the file python_mongodm-0.1.6.tar.gz.

File metadata

  • Download URL: python_mongodm-0.1.6.tar.gz
  • Upload date:
  • Size: 9.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.8

File hashes

Hashes for python_mongodm-0.1.6.tar.gz
Algorithm Hash digest
SHA256 a73d3c9b9cafcf7aa1a97d0604cf74bae3cc5f9e06cf99d0c072d228c1ff9fce
MD5 1aa87a2e8f5bd03efecb28f5bb07b472
BLAKE2b-256 5e8660615bab77c881bee1bc13f2ce6682fa5c394654dd4f79fbd0e9f4d27170

See more details on using hashes here.

File details

Details for the file python_mongodm-0.1.6-py3-none-any.whl.

File metadata

  • Download URL: python_mongodm-0.1.6-py3-none-any.whl
  • Upload date:
  • Size: 8.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.8

File hashes

Hashes for python_mongodm-0.1.6-py3-none-any.whl
Algorithm Hash digest
SHA256 905e3e4840289142af0d10836c392b0be1e88927e0ea59641aa15d2a6967acf5
MD5 34d7890fc9c73a7780e9eb8f721bffe5
BLAKE2b-256 338fa2fadd173f10a105871d2b6c15acca23c2196d1b11776c9ea18b87fc86b8

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