| Name | python-mongodm JSON |
| Version |
0.1.2
JSON |
| download |
| home_page | None |
| Summary | Asynchronous Python ODM for MongoDB based on Motor |
| upload_time | 2024-09-11 09:00:31 |
| maintainer | None |
| docs_url | None |
| author | Ferréol Jeannot-Lorente |
| requires_python | >=3.6 |
| license | None |
| keywords |
|
| VCS |
 |
| bugtrack_url |
|
| requirements |
No requirements were recorded.
|
| Travis-CI |
No Travis.
|
| coveralls test coverage |
No coveralls.
|
# MongODM
MongODM is a simple, lightweight, and asynchronous Object Document Mapper for MongoDB.
It uses Pydantic and Motor.
## Installation
```bash
pip install python-mongodm
```
## Usage
```python
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`.
```python
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.
```python
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.
```python
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.
```python
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.
```python
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](https://choosealicense.com/licenses/mit/)
Raw data
{
"_id": null,
"home_page": null,
"name": "python-mongodm",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": null,
"keywords": null,
"author": "Ferr\u00e9ol Jeannot-Lorente",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/e8/c8/691ce4ef1bd68a43816d2fdcd735a7446e24ba5c5a82ac1348ec5e1d1ffb/python_mongodm-0.1.2.tar.gz",
"platform": null,
"description": "# MongODM\n\nMongODM is a simple, lightweight, and asynchronous Object Document Mapper for MongoDB.\nIt uses Pydantic and Motor.\n\n## Installation\n\n```bash\npip install python-mongodm\n```\n\n## Usage\n\n```python\nimport mongodm\nfrom motor.motor_asyncio import AsyncIOMotorClient\n\nmongodm.set_config(AsyncIOMotorClient('mongodb://localhost:27017'), 'test')\n\n\nclass Entity(mongodm.MongoODMBase):\n __collection_name__ = 'my_entity'\n __protected_attributes__ = {'protected'} # Writable on first creation, but not on updates\n\n title: str\n description: str\n protected: str\n\n\nitem = Entity(title='title', description='description', protected='protected')\nawait item.save() # Commit in DB\nitem.dict() # {'title': 'title', 'description': 'description', 'protected': 'protected', created_at: datetime.datetime(), updated_at: None, deleted_at: None}\n\ndb_items = await Entity.get_all() # List of instances from db\ndb_items[0].title = 'modification'\nawait db_items[0].save()\nawait db_items[0].delete()\n\n# To change multiples attributes simultaneously, pydantic constructor style\nnew_attributes_dict = {'title': 'edited', 'description': 'edited'}\nitem.set_attributes(**new_attributes_dict) \n\n# You can also use the collection getter directly to send a raw query to the database\nrandom_item = await Entity.get_collection().aggregate([{'$sample': {'size': 1}}]).to_list(1)[0]\n```\n\n\n\nThe 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.\n\n\nIt 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.\n\n\nThe configuration for the database can be set with `set_config()` \nYou can enable soft delete by using set_config with `soft_delete=True`.\n```python\nmongodm.set_config(AsyncIOMotorClient(\"mongodb://localhost:27017\"), \"my_database\", soft_delete=True)\n```\n\nSince the whole thing is based on Pydantic, you can use all the features of Pydantic.\n\n```python\nfrom pydantic import Field, validator\n\nclass Entity(mongodm.MongoODMBase):\n __collection_name__ = 'my_entity'\n title: str\n description: str\n protected: str = Field(default='protected', description='This is a protected field')\n\n @validator('title')\n def title_must_contain_space(cls, v):\n if ' ' not in v:\n raise ValueError('must contain a space')\n return v.title()\n```\n\nYou can even modify the pydantic config by creating a new class that inherits from MongoODMBase and override the pydantic Config subclass.\n\n```python\nclass MyBase(mongodm.MongoODMBase):\n class Config(mongodm.MongoODMBase.Config):\n allow_population_by_field_name = True\n\nclass Entity(MyBase):\n ...\n```\n\n\n## Encrypted fields\nIt 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.\nMongODM will automatically decrypt the data when it is retrieved from the database.\nYou will need to configure the encryption by using `set_encryption_config()`.\n\nThis approach is very opinionated, and is proposed as an alternative if you don't want to use the MongoDB encryption features.\n\n```python\nimport mongodm\n\nmongodm.set_encryption_config(\n public_key='YOUR_RSA_PUBLIC_KEY_VALUE',\n private_key='YOUR_RSA_PRIVATE_KEY_VALUE'\n)\n```\n\n\n## Hooks\nYou can use hooks to execute code before or after a variety of events. The following hooks are available:\n\n- `before_create()`: Before the object is created in the database.\n- `after_create()`: After the object is created in the database.\n- `before_save()`: Before the object is saved in the database, called both during creation and update operations.\n- `after_save()`: After the object is saved in the database, called both during creation and update operations.\n- `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.\n- `after_update()`: After the object is updated in the database\n- `after_find()`: After the object is found in the database\n- `before_delete()`: Before the object is deleted in the database\n- `after_delete()`: After the object is deleted in the database\n- `after_soft_delete()` (only if soft delete is enabled)\n- `after_hard_delete()` (only if soft delete is disabled)\n\nAll 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.\n\n```python\ndef before_create(self):\n self.created_at = datetime.now().isoformat()\n\n# You must use the same method signature and return it at the end\ndef before_update(self, payload):\n payload['updated_at'] = datetime.now().isoformat()\n return payload\n```\n\n## Contributing\n\nContributions are welcome! Please open an issue or a pull request.\nWe are looking for reviews and feedback on the basic design of the library.\n\n## License\n\n[MIT](https://choosealicense.com/licenses/mit/)\n",
"bugtrack_url": null,
"license": null,
"summary": "Asynchronous Python ODM for MongoDB based on Motor",
"version": "0.1.2",
"project_urls": {
"Bug Tracker": "https://github.com/tritons-io/MongODM/issues",
"Homepage": "https://github.com/tritons-io/MongODM"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "56eb6672b23a3b64b86967f20113220969a8acb81cfac37a443cb9d71522fa8e",
"md5": "ef63c4e732f82423ebc71579a566ae73",
"sha256": "8d08965f549e81723669daf60f3d8bf5b57490d888dcc3f1c2d4245a6d79e17c"
},
"downloads": -1,
"filename": "python_mongodm-0.1.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "ef63c4e732f82423ebc71579a566ae73",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6",
"size": 8108,
"upload_time": "2024-09-11T09:00:30",
"upload_time_iso_8601": "2024-09-11T09:00:30.091809Z",
"url": "https://files.pythonhosted.org/packages/56/eb/6672b23a3b64b86967f20113220969a8acb81cfac37a443cb9d71522fa8e/python_mongodm-0.1.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "e8c8691ce4ef1bd68a43816d2fdcd735a7446e24ba5c5a82ac1348ec5e1d1ffb",
"md5": "8c4e1ab248a65dd08480d104f0b43681",
"sha256": "a0dce7d34acc89d25a987e2dfd12a91523d7e1b9f737e9eab8a3cdddc49701a0"
},
"downloads": -1,
"filename": "python_mongodm-0.1.2.tar.gz",
"has_sig": false,
"md5_digest": "8c4e1ab248a65dd08480d104f0b43681",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 9086,
"upload_time": "2024-09-11T09:00:31",
"upload_time_iso_8601": "2024-09-11T09:00:31.687653Z",
"url": "https://files.pythonhosted.org/packages/e8/c8/691ce4ef1bd68a43816d2fdcd735a7446e24ba5c5a82ac1348ec5e1d1ffb/python_mongodm-0.1.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-09-11 09:00:31",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "tritons-io",
"github_project": "MongODM",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "python-mongodm"
}