Skip to main content

MongoGetterSetter - A Clean MongoDB Getter Setter API for Python

PyPI version Downloads Downloads Downloads License: MIT

MongoGetterSetter is a metaclass that provides a convenient getter and setter API for instances of the classes that use it, allowing natural operations in Python objects to easily reflect in MongoDB documents.

The idea is to convert MongoDB Document into a Python Object of Type MongoGetterSetter in High Level, and all other document's sub documents are treated as dict wrapped with MongoDictWrapper and primitive datatypes like int, bool float are accessed as attributes of MongoDictWrapper and MongoDataWrapper. MongoDataWrapper is to handle lists and all list/array operations.

This library is created with performance in mind so that only when you initialize the MongoGetterSetter class for the first time into a Collection object, it will fetch the document from the MongoDB only once and cache it in the memory. All the subsequent operations will be done on the cached document. If you want to refresh the document, you can call refresh() method on the object. If you make changes to the object, it will be reflected in the MongoDB document and the Python Object will be updated with the new changes.

To Get Started, we initialize Employee and EmployeeCollection class with _collection and _filter_query as mandatory attributes for MongoGetterSetter to function properly. These 2 attributes are used internally to do further manipulations to MongoDB documents. You can change the _filter_query attribute to customize the filter query as per your needs. _collection should point to the MongoDB collection.

Usage of MongoGetterSetter metaclass

from pymongo import MongoClient
from mongogettersetter import MongoGetterSetter

# Connect to the MongoDB database and collection

client = MongoClient("mongodb://localhost:27017/")
db = client["example_db"]
collection = db["employee"]

# Wrapper for MongoDB Collection with metaclass, use this inside your actual class.
class EmployeeCollection(metaclass=MongoGetterSetter):
    def __init__(self, _id):
        self._filter_query = {"id": _id} # or the ObjectID, at your convinence
        self._collection = collection # Should be a pymongo.MongoClient[database].collection

class Employee:
    def __init__(self, _id):
        self._filter_query = {"id": _id}
        self._collection = collection
        self.collection = EmployeeCollection(_id)

        # Create a new document if it doesn't exist
        if self.collection.get() is None:
            self._collection.insert_one(self._filter_query)
    
    def someOtherOperation(self):
        self.collection.hello = "Hello World"  

Now, save the above code in a file named employee.py and run the following command in the same directory:

$ python3 -i employee.py

This will run the contents of employee.py in interactive mode. Now, you can create an instance of EmployeeCollection in Employee class and do operations on it.

Before that, assume you have a MongoDB Collection called employee with an object like this:

{
  "_id": "640311ab0469a9c4eaf3d2bd",
  "id": 4051,
  "email": "manoj123@gmail.com",
  "password": "SomeNew SecurePassword",
  "about": null,
  "token": "7f471974-ae46-4ac0-a882-1980c300c4d6",
  "country": "India",
  "location": null,
  "lng": 0,
  "lat": 0,
  "dob": null,
  "gender": 0,
  "userType": 1,
  "userStatus": 1,
  "profilePicture": "Images/9b291404-bc2e-4806-88c5-08d29e65a5ad.png",
  "coverPicture": "Images/44af97d9-b8c9-4ec1-a099-010671db25b7.png",
  "enablefollowme": false,
  "sendmenotifications": false,
  "sendTextmessages": false,
  "enabletagging": false,
  "createdAt": "2020-01-01T11:13:27.1107739",
  "updatedAt": "2020-01-02T09:16:49.284864",
  "livelng": 77.389849,
  "livelat": 28.6282231,
  "liveLocation": "Unnamed Road, Chhijarsi, Sector 63, Noida, Uttar Pradesh 201307, India",
  "creditBalance": 130,
  "myCash": 0,
  "data": {
    "name": "array_test",
    "arr": [
      1,
      2,
      3,
      4,
      5,
      6,
      7,
      8
    ],
    "hobies": {
      "composer": [
        "anirudh",
        {
          "co_singer": [
            "rakshitha",
            "divagar",
            "sibi"
          ]
        },
        "yuvan"
      ],
      "music": "helo"
    }
  },
  "scores": [
    {
      "subject": "math",
      "score": 100
    },
    {
      "subject": "physics",
      "score": 85
    },
    {
      "subject": "chemistry",
      "score": 95
    }
  ],
  "fix": 1,
  "hello": 1,
  "recent_views": [
    200
  ],
  "exam": "",
  "subject": "",
  "arr": {
    "name": "sibidharan",
    "pass": "hello",
    "score": {
      "subject": {
        "minor": "zoology",
        "major": "biology",
        "others": [
          "evs",
          {
            "name": "shiro",
            "inarr": [
              200,
              2,
              3,
              {
                "sub": "testsub",
                "newsu": "aksjdad",
                "secret": "skdjfnsdkfjnsdfsdf"
              },
              4,
              12
            ]
          }
        ]
      },
      "score": 40,
      "new": "not7",
      "hello": {
        "arr": [
          5,
          2
        ]
      }
    }
  },
  "name": "ManojKumar",
  "d": [
    1,
    3,
    4,
    5
  ],
  "score": {},
  "hgf": 5
}

This can be accessed by creating an instance of EmployeeCollection class with the proper id as given in the self._filter_query. If such ID doesn't exist, Employee class will create a new document with the given id when initialized. EmployeeCollection is designed to replace your MongoDB collection object, so you can use it as a drop-in replacement for your MongoDB collection object inside any class, and perform operations in it according to this documentation.

For example:

>>> e = EmployeeCollection(4051)

Now this e object is an instance of EmployeeCollection class, which is a subclass of MongoGetterSetter metaclass. When inside Employee class, it can be accessed like self.collection. This object is a wrapper around the MongoDB document, which is fetched from the MongoDB collection using the self._filter_query from the self._collection attribute. You can access the MongoDB document and do CURD essential operations just by accessing this object's attributes/indexes. For the available methods, see the MongoDataWrapper and MongoDictWrapper methods. For example:

>>> e = EmployeeCollection(4051)
>>> e
{'_id': ObjectId('640311ab0469a9c4eaf3d2bd'), 'id': 4051, 'email': 'manoj123@gmail.com', 'password': 'SomeNew SecurePassword', 'about': None, 'token': '7f471974-ae46-4ac0-a882-1980c300c4d6', 'country': 'India', 'location': None, 'lng': 0, 'lat': 0, 'dob': None, 'gender': 0, 'userType': 1, 'userStatus': 1, 'profilePicture': 'Images/9b291404-bc2e-4806-88c5-08d29e65a5ad.png', 'coverPicture': 'Images/44af97d9-b8c9-4ec1-a099-010671db25b7.png', 'enablefollowme': False, 'sendmenotifications': False, 'sendTextmessages': False, 'enabletagging': False, 'createdAt': '2020-01-01T11:13:27.1107739', 'updatedAt': '2020-01-02T09:16:49.284864', 'livelng': 77.389849, 'livelat': 28.6282231, 'liveLocation': 'Unnamed Road, Chhijarsi, Sector 63, Noida, Uttar Pradesh 201307, India', 'creditBalance': 130, 'myCash': 0, 'data': {'name': 'array_test', 'arr': [1, 2, 3, 4, 5, 6, 7, 8], 'hobies': {'composer': ['anirudh', {'co_singer': ['rakshitha', 'divagar', 'sibi']}, 'yuvan'], 'music': 'helo'}}, 'scores': [{'subject': 'math', 'score': 100}, {'subject': 'physics', 'score': 85}, {'subject': 'chemistry', 'score': 95}], 'fix': 1, 'hello': 1, 'recent_views': [200], 'exam': '', 'subject': '', 'arr': {'name': 'sibidharan', 'pass': 'hello', 'score': {'subject': {'minor': 'zoology', 'major': 'biology', 'others': ['evs', {'name': 'shiro', 'inarr': [200, 2, 3, {'sub': 'testsub', 'newsu': 'aksjdad', 'secret': 'skdjfnsdkfjnsdfsdf'}, 4, 12]}]}, 'score': 40, 'new': 'not7', 'hello': {'arr': [5, 2]}}}, 'name': 'ManojKumar', 'd': [1, 3, 4, 5], 'score': {}, 'hgf': 5}
>>> e.id
4051
>>> e.name
ManojKumar

The MongoDB Document's root level attributes are directly accessible as the attributes of the MongoGetterSetter object. For example, e.id can also be accessible as e['id'] and e.name can also be accessible as e['name'].

For Example:

>>> e.name = "S. Manoj Kumar"
>>> e.name
S. Manoj Kumar
>>> e.data
{'name': 'array_test', 'arr': [1, 2, 3, 4, 5, 6, 7, 8], 'hobies': {'composer': ['anirudh', {'co_singer': ['rakshitha', 'divagar', 'sibi']}, 'yuvan'], 'music': 'helo'}}
>>> type(e.data)
<class 'mongogettersetter.MongoDataWrapper'>
>>> e.data.name = "ThisIsAwesmoe"
>>> e.data
{'name': 'ThisIsAwesmoe', 'arr': [1, 2, 3, 4, 5, 6, 7, 8], 'hobies': {'composer': ['anirudh', {'co_singer': ['rakshitha', 'divagar', 'sibi']}, 'yuvan'], 'music': 'helo'}}
>>> 

The MongoDataWrapper class is used to wrap the MongoDB document datatypes to provide MongoDB Array/List Operations over a simple, straightforward API to perform various operations on the MongoDB collection.

You can perform almost all basic array operations MongoDB supports. For example, you can use e.data.arr.push(9) to append a new element to the arr array. Similarly, you can use e.data.arr.pop() to pop the last element from the arr array. You can also use e.data.arr.remove(2) to remove the element 2 from the arr array. You can also use e.data.arr.insert(0, [1,2,3]) to insert the element [1,2,3] at the beginning of the arr array. You can also use e.data.arr[0] = 0 to set the first element of the arr array to 0. You can also use e.data.arr[0] to get the first element of the arr array.

>>> e.data
{'name': 'ThisIsAwesmoe', 'arr': [1, 2, 3, 4, 5, 6, 7, 8], 'hobies': {'composer': ['anirudh', {'co_singer': ['rakshitha', 'divagar', 'sibi']}, 'yuvan'], 'music': 'helo'}}
>>> type(e.data)
<class 'mongogettersetter.MongoDictWrapper'>
>>> type(e.data.get())
<class 'dict'>
>>> e.data.arr.push(9)
True
>>> e.data
{'name': 'ThisIsAwesmoe', 'arr': [1, 2, 3, 4, 5, 6, 7, 8, 9], 'hobies': {'composer': ['anirudh', {'co_singer': ['rakshitha', 'divagar', 'sibi']}, 'yuvan'], 'music': 'helo'}}
>>> e.data.arr[1] = 100
>>> e.data.arr
[1, 100, 3, 4, 5, 6, 7, 8, 9]
>>> e.data.arr[1]
100

All List/Array are wrapped with MongoDataWrapper and all dictionary are wrapped with MongoDictWrapper. Access documents in any depth, either as attributes or as keys, to access nested data. For example, e.data.hobies is a nested dictionary, so you can access the hobies dictionary as e.data.hobies or e.data['hobies']. Similarly, e.data.hobies.composer is a nested list, so you can access the composer list as e.data.hobies.composer or e.data.hobies['composer']. Similarly, e.data.hobies.composer[1] is a nested dictionary, so you can access the co_singer list as e.data.hobies.composer[1].co_singer or e.data.hobies.composer[1]['co_singer']. Perform all possible operations on all the nested data, limited to the MongoDB-supported operations.

>>> e.data.hobies
{'composer': ['anirudh', {'co_singer': ['rakshitha', 'divagar', 'sibi']}, 'yuvan'], 'music': 'helo'}
>>> e.data.hobies.composer
['anirudh', {'co_singer': ['rakshitha', 'divagar', 'sibi']}, 'yuvan']
>>> e.data.hobies.composer.push('rahman')
True
>>> e.data.hobies.composer
['anirudh', {'co_singer': ['rakshitha', 'divagar', 'sibi']}, 'yuvan', 'rahman']
>>> e.data.hobies.composer[1]
{'co_singer': ['rakshitha', 'divagar', 'sibi']}
>>> e.data.hobies.composer[1].co_singer
['rakshitha', 'divagar', 'sibi']
>>> e.data.hobies.composer[1].co_singer.pop()
True
>>> e.data.hobies.composer[1].co_singer
['rakshitha', 'divagar']
>>> e.data.hobies.composer[1].co_singer.insert(0, 'sushila')
True
>>> e.data.hobies.composer[1].co_singer
['sushila', 'rakshitha', 'divagar']
>>> e.data.hobies
{'composer': ['anirudh', {'co_singer': ['sushila', 'rakshitha', 'divagar']}, 'yuvan', 'rahman'], 'music': 'helo'}
>>> e.data.hobies.music = 'melody'
>>> e.data.hobies
{'composer': ['anirudh', {'co_singer': ['sushila', 'rakshitha', 'divagar']}, 'yuvan', 'rahman'], 'music': 'melody'}
>>> e.data.hobies.composer[1].main_singer = 'SPB'
>>> e.data.hobies
{'composer': ['anirudh', {'co_singer': ['sushila', 'rakshitha', 'divagar'], 'main_singer': 'SPB'}, 'yuvan', 'rahman'], 'music': 'melody'}
>>> e.data.hobies.composer
['anirudh', {'co_singer': ['sushila', 'rakshitha', 'divagar'], 'main_singer': 'SPB'}, 'yuvan', 'rahman']
>>> e.data.hobies.composer[1].main_singer
'SPB'
>>> type(e.data.hobies.composer[1].main_singer)
<class 'str'>
>>> type(e.data.hobies.composer)
<class 'mongogettersetter.MongoDataWrapper'>
>>> type(e.data.hobies.composer[1])
<class 'mongogettersetter.MongoDictWrapper'>
>>> e.data.hobies.composer[1].get('co_singer')
['sushila', 'rakshitha', 'divagar']
>>> e.data.hobies.composer[1].get()
{'co_singer': ['sushila', 'rakshitha', 'divagar'], 'main_singer': 'SPB'}
>>> type(e.data.hobies.composer[1].get())
<class 'dict'>

MongoGetterSetter

MongoGetterSetter is a metaclass that provides a convenient getter and setter API for instances of the classes that use it, allowing natural operations in Python objects to easily reflect in MongoDB documents.

Methods

  • __getattr__(self, key): Returns a MongoDataWrapper instance for the given key. See below for the capabilities of `MongoDataWrapper``

    Example:

    obj = EmployeeCollection(_id)
    result = obj.some_key
    
  • __getitem__(self, key, value): Gets the value of the specified key from the MongoDB document.

    Example:

    print(obj['some_key'])
    
  • __setattr__(self, key, value): Sets the value of the specified key in the MongoDB document.

    Example:

    obj.some_key = "new_value"
    
  • __setitem__(self, key, value): Sets the value of the specified key in the MongoDB document.

    Example:

    obj['some_key'] = "new_value"
    
  • __contains__(self, key): Checks if the MongoDB document contains the specified key.

    Example:

    if "some_key" in obj:
        print("Key exists")
    
  • __str__(self): Returns a string representation of the MongoDB document.

    Example:

    print(obj)
    
  • __delitem__(self, key): Removes the specified key from the MongoDB document.

    Example:

    del obj['some_key']
    
  • __delattr__(self, key): Removes the specified key from the MongoDB document.

    Example:

    del obj.some_key
    
  • delete(self): Removes document itself from the MongoDB

    Example:

    obj.delete()
    
  • get(self): Returns the MongoDB document.

    Example:

    print(obj.get())
    
  • set(self, data): Sets the given updated document in the MongoDB collection

    Example:

    obj.set({
        "password": "$2$somenewpassword",
        "country": "Malaysia"
    })
    
  • refresh(self): Refreshes the object with the latest data from the MongoDB collection

    Example:

    obj.refresh()
    

MongoDataWrapper

MongoDataWrapper is a subscriptable class, which wraps MongoDB document datatypes to provide MongoDB Array/List Operations over a simple, straightforward API to perform various operations on the MongoDB collection. Check the list of methods for the allowed operations.

Methods

  • __init__(self, _id, key, collection): Initialize the instance with the given _id, key, and collection.

  • get(self): Returns the value of the key in the MongoDB document.

  • in: Use in to check if the given value is present in the array of the document's key.

  • push(self, *values, maximum=-1): Pushes one or more values into the array of the document's key. If maximum is specified, it will limit the array size to the maximum value.

  • addToSet(self, value): Adds a value to the array of the document's key only if it doesn't exist in the array.

  • pop(self, direction=1): Removes the first (direction=-1) or the last (direction=1) element from the array of the document's key.

  • pull(self, value): Removes the specified value from the array of the document's key.

  • pullAll(self, *values): Removes all occurrences of the specified values from the array of the document's key.

  • matchSize(self, value): Checks if the size of the array of the document's key is equal to the given value.

  • elemMatch(self, **kvalues): Checks if the array of the document's key contains at least one element that matches the specified key-value pairs in kvalues.

  • matchAll(self, *values): Checks if the array of the document's key contains all the specified values.

  • update(self, field, match, **kvalues): Updates the nested field field of the document's key where the field value matches match, with the key-value pairs provided in kvalues.

  • insert(self, index, value): Inserts the given value at the specified index in the array of the document's key.

  • index(self, value): Find the index of the given value in array. It will return -1 if the value is not present in the list.

  • refresh(self): Refreshes the object with the latest data from the MongoDB collection.

  • delete(self): Delets the key from MongoDB Document

  • __getitem__(self, index): Returns the value of the array of the document's key at the specified index.

  • __setitem__(self, index, value): Sets the value of the array of the document's key at the specified index to the given value.

  • __delitem__(self, index): Removes the value of the array of the document's key at the specified index.

  • __len__(self): Returns the length of the array of the document's key.

  • __str__(self): Returns a string representation of the value of the document's key.

  • __repr__(self): Returns a string representation of the value of the document's key.

MongoDictWrapper

MongoDictWrapper is a class that inherits from the dict class and extends its functionalities to access dictionary keys as attributes. It allows you to access, modify, and manipulate MongoDB documents using Python dictionaries. When a MongoDataWrapper returns a dict, it automatically is wrapped with MongoDictWrapper, when it returns a list, it automatically is wrapped with MongoDataWrapper to allow manipulation of MongoDB object inside a MongoDB object, like a dict inside a dict. If you wish to access the value as default datatype, consider get() method.

Methods

  • __init__(self, *args, **kwargs): Constructor method that initializes the base dict class.

  • prepare(self, _id, key, collection, filter_query): This method initializes the internal data structure that stores information about the document's location in the MongoDB collection.

  • refresh(self): Refreshes the object with the latest data from the MongoDB collection.

  • __getitem__(self, key): Overrides the base dict method to return a wrapped MongoDictWrapper when accessing a nested dictionary.

  • __setitem__(self, key, value): Overrides the base dict method to update the MongoDB document when setting a key-value pair.

  • __delattr__(self, key): Overrides the base dict method to delete a key-value pair from the MongoDB document when deleting an attribute.

  • __getattr__(self, key): Overrides the base dict method to return a wrapped MongoDictWrapper when accessing a nested dictionary.

  • __setattr__(self, key, value): Overrides the base dict method to update the MongoDB document when setting a key-value pair.

  • __delitem__(self, key): Overrides the base dict method to delete a key-value pair from the MongoDB document when deleting an item.

  • get(self, key, default=None): Overrides the base dict method to return the value of the key in the MongoDB document, or the default value if the key is not present.

  • pop(self, key, default=None): Overrides the base dict method to remove and return the value of the key in the MongoDB document, or the default value if the key is not present.

  • update(self, other): Overrides the base dict method to update the MongoDB document with the key-value pairs from the other dictionary or iterable.

  • delete(self)` Deletes the key from MongoDB Document

  • clear(self): Overrides the base dict method to remove all key-value pairs from the MongoDB document.

  • __len__(self): Overrides the base dict method to return the number of key-value pairs in the MongoDB document.

  • __str__(self): Overrides the base dict method to return a string representation of the MongoDB document.

  • __repr__(self): Overrides the base dict method to return a string representation of the MongoDB document.

Examples

To provide a more detailed example, let's assume you have a MongoDB collection named people with the following documents:

[
    {
        "id": 1,
        "name": "Alice",
        "age": 30,
        "skills": ["Python", "Django", "JavaScript"],
        "contact": {
            "email": "alice@example.com",
            "phone": "555-1234"
        },
        "projects": [
            {
                "title": "Project A",
                "status": "completed"
            },
            {
                "title": "Project B",
                "status": "in progress"
            }
        ]
    },
    {
        "id": 2,
        "name": "Bob",
        "age": 25,
        "skills": ["Java", "Spring", "JavaScript"],
        "contact": {
            "email": "bob@example.com",
            "phone": "555-5678"
        },
        "projects": [
            {
                "title": "Project X",
                "status": "completed"
            },
            {
                "title": "Project Y",
                "status": "in progress"
            }
        ]
    }
]

Now, let's create a class called People and PeopleCollection with MongoGetterSetter as its metaclass.

from pymongo import MongoClient
from mongogettersetter import MongoGetterSetter

# Connect to the MongoDB database and collection
client = MongoClient("mongodb://localhost:27017/")
db = client["example_db"]
people_collection = db["people"]

# Wrapper for MongoDB Collection with metaclass, use this inside your actual class.
class PeopleCollection(metaclass=MongoGetterSetter):
    def __init__(self, _id):
        self._filter_query = {"id": _id}  # or the ObjectID, at your convenience
        self._collection = people_collection  # Should be a pymongo.MongoClient[database].collection

class People():
    def __init__(self, _id):
        self.collection = PeopleCollection(_id)
        self._filter_query = {"id": _id}
        self._collection = people_collection
        if self.collection.get() is None:
            self._collection.insert_one(self._filter_query)
    
    def someOtherOperation(self):
        self.collection.hello = "Hello World"       

Create a PeopleCollection object for Alice with id = 1

alice = PeopleCollection(1)

Access and modify Alice's name

print(alice.name)  # Output: 'Alice'
alice.name = "Alice Johnson"
print(alice.name)  # Output: 'Alice Johnson'

Check if Alice's document has a 'contact' field

if 'contact' in alice:
    print("Contact field exists")

Access and modify Alice's email

print(alice.contact)  # Output: {'email': 'alice@example.com', 'phone': '555-1234'}
alice.contact.email = "alice.johnson@example.com"
print(alice.contact.email)  # Output: 'alice.johnson@example.com'

Access and modify Alice's skills

print(alice.skills)# Output: ['Python', 'Django', 'JavaScript']

print(alice.skills.get())  # Output: ['Python', 'Django', 'JavaScript']
alice.skills.push("React", maximum=4)
print(alice.skills.get())  # Output: ['Python', 'Django', 'JavaScript', 'React']
alice.skills.pop(direction=1)
print(alice.skills.get())  # Output: ['Python', 'Django', 'JavaScript']
alice.skills.pop(direction=-1)
print(alice.skills.get())  # Output: [ 'Django', 'JavaScript']

Access and modify Alice's projects

print(alice.projects.get())  # Output: [{'title': 'Project A', 'status': 'completed'}, {'title': 'Project B', 'status': 'in progress'}]
alice.projects.update("title", "Project A", status="archived")
print(alice.projects.get())  # Output: [{'title': 'Project A', 'status': 'archived'}, {'title': 'Project B', 'status': 'in progress'}]

More MongoDataWrapper examples

Create a People object for Alice with id = 1

alice = People(1)

Create MongoDataWrapper instances for Alice's skills and projects

alice_skills = alice.skills
alice_projects = alice.projects

Examples for each method of the MongoDataWrapper class

  1. get()
print(alice_skills.get())  # Output: ['Python', 'Django', 'JavaScript']
  1. __contains__
print("Python" in alice_skills)  # Output: True
  1. push()
alice_skills.push("React", "Java", maximum=5)
print(alice_skills.get())  # Output: ['Python', 'Django', 'JavaScript', 'React', 'Java']
  1. addToSet()
alice_skills.addToSet("C++")
print(alice_skills.get())  # Output: ['Python', 'Django', 'JavaScript', 'React', 'Java', 'C++']
  1. pop()
alice_skills.pop(direction=1)
print(alice_skills.get())  # Output: ['Python', 'Django', 'JavaScript', 'React', 'Java']
alice_skills.pop(direction=-1)
print(alice_skills.get())  # Output: ['Django', 'JavaScript', 'React', 'Java']
  1. pull()
alice_skills.pull("Java")
print(alice_skills.get())  # Output: ['Python', 'Django', 'JavaScript', 'React']
  1. pullAll()
alice_skills.pullAll("Python", "React")
print(alice_skills.get())  # Output: ['Django', 'JavaScript']
  1. matchSize()
print(alice_skills.size(2))  # Output: True
  1. elemMatch()
print(alice_projects.elemMatch(title="Project A", status="completed"))  # Output: True
  1. matchAll()
print(alice_skills.all("Django", "JavaScript"))  # Output: True
  1. update()
alice_projects.update("title", "Project A", status="archived")
print(alice_projects.get())  # Output: [{'title': 'Project A', 'status': 'archived'}, {'title': 'Project B', 'status': 'in progress'}]
  1. __len__()
print(len(alice_skills))  # Output: 2
  1. __str__() and __repr__()
print(alice_skills)  # Output: ['Django', 'JavaScript']
print(repr(alice_skills))  # Output: ['Django', 'JavaScript']

More MongoDictWrapper examples

>>> e = Employee(4051)
>>> e
{'_id': ObjectId('640311ab0469a9c4eaf3d2bd'), 'id': 4051, 'name': 'Manoj', 'email': 'manoj123@gmail.com', 'password': 'different password', 'about': None, 'token': '7f471974-ae46-4ac0-a882-1980c300c4d6', 'country': None, 'location': None, 'lng': 0, 'lat': 0, 'dob': None, 'gender': 0, 'userType': 1, 'userStatus': 1, 'profilePicture': 'Images/9b291404-bc2e-4806-88c5-08d29e65a5ad.png', 'coverPicture': 'Images/44af97d9-b8c9-4ec1-a099-010671db25b7.png', 'enablefollowme': False, 'sendmenotifications': False, 'sendTextmessages': False, 'enabletagging': False, 'createdAt': '2020-01-01T11:13:27.1107739', 'updatedAt': '2020-01-02T09:16:49.284864', 'livelng': 77.389849, 'livelat': 28.6282231, 'liveLocation': 'Unnamed Road, Chhijarsi, Sector 63, Noida, Uttar Pradesh 201307, India', 'creditBalance': 127, 'myCash': 0, 'data': [4, 3, 4, 5, 7], 'arr': {'name': 'shiro', 'pass': 'hello', 'score': {'subject': {'minor': 'physics', 'major': 'science'}, 'score': 95}}, 'scores': [{'subject': 'math', 'score': 95}, {'subject': 'physics', 'score': 85}, {'subject': 'chemistry', 'score': 95}], 'recent_views': [4, 4, 4, 4, 4, 4, 4, 4, 4], 'fix': 1, 'hello': 1}
>>> e.arr
{'name': 'shiro', 'pass': 'hello', 'score': {'subject': {'minor': 'physics', 'major': 'science'}, 'score': 95}}
>>> e.arr['name'] = 'sibidharan' # MongoDataWrapper is also Subscriptable
>>> e.arr
{'name': 'sibidharan', 'pass': 'hello', 'score': {'subject': {'minor': 'physics', 'major': 'science'}, 'score': 95}}
>>> e.arr.score # Queried from the MongoDB directly
{'subject': {'minor': 'physics', 'major': 'science'}, 'score': 95}
>>> e.arr.score['subject']
{'minor': 'physics', 'major': 'science'}
>>> e.arr.score.subject
{'minor': 'physics', 'major': 'science'}
>>> e.arr.score.subject.minor = 'chemistry'
{'minor': 'physics', 'major': 'science'}
# is same as the following
>>> e.arr.score['subject']['minor'] = 'chemistry' # All change are reflected in MongoDB Document
>>> e.arr
{'name': 'sibidharan', 'pass': 'hello', 'score': {'subject': {'minor': 'chemistry', 'major': 'science'}, 'score': 95}}
>>> del e.arr.score['subject'] # Can delete any key in dictionary
>>> del e.arr # Can delete a key itself from the MongoDB Document
>>> e.delete() # Delete the document itself

High-level Overview of the code for contributors to better understand the implementation

Any and all contributions are welcome ❤️

  1. MongoDictWrapper: A wrapper for dictionaries that provides additional methods for interaction with MongoDB documents.

    Methods:

    • prepare
    • __getitem__
    • __setitem__
    • __delitem__
    • get
    • pop
    • update
    • clear
    • delete
    • refresh
  2. MongoDataWrapper: A wrapper class for the data stored in MongoDB documents.

    Methods:

    • get
    • inArray
    • push
    • addToSet
    • pop
    • pull
    • pullAll
    • size
    • elemMatch
    • all
    • update
    • delete
    • refresh
    • __len__
    • __str__
    • __repr__
    • __getattr__
    • __getitem__
    • __setattr__
    • __setitem__
    • __delitem__
    • __delattr__
    • __contains__
  3. MongoGetterSetter: A metaclass that provides a way to override the default behavior of __getattr__, __setattr__, __contains__, __str__, __repr__, and __delattr__ to work with MongoDB documents.

    Nested class: PyMongoGetterSetter

    Methods:

    • __getattr__
    • __getitem__
    • __setattr__
    • __setitem__
    • __contains__
    • __str__
    • __repr__
    • __delattr__
    • __delitem__
    • delete
    • refresh

Credits

Thanks to GPT-4 for helping me write this documentation. If you find any errors or something doesn't work as the documentation says, raise an issue here https://git.selfmade.ninja/sibidharan/pymongogettersetter

Metadata

Release files for mongogettersetter 1.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mongogettersetter 1.5.0
File Size Uploaded Provenance
mongogettersetter-1.5.0.tar.gz 25.0 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for mongogettersetter 1.5.0
File Interpreter ABI Platform
mongogettersetter-1.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 37.8 kB

Release files / mongogettersetter-1.5.0.tar.gz

Download URL mongogettersetter-1.5.0.tar.gz
Size 25.0 kB
Tags Source
SHA-256 checksum
How to use checksums
f2100c43b145587b679b2eabeabae0a7f96c487169d06be519f3a13d787a24ea
BLAKE2b-256 checksum
How to use checksums
c915db7db020276caffb99912b69132e146ac1bf79e6a87f9d434219b236faa9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.11.4

Release files / mongogettersetter-1.5.0-py3-none-any.whl

Download URL mongogettersetter-1.5.0-py3-none-any.whl
Size 12.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e6bc4e8d024fdf76ec99a6618f18a63b39319d4252e4681e853559dc1933dda9
BLAKE2b-256 checksum
How to use checksums
f067fa6b915ea63f2c77c2b217020cbc02b8095f329bd98ed5497fbd9caecd4c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.11.4

Security for mongogettersetter 1.5.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.5.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page