mongodol.trans#
Transformative functionality
Functions
|
Wrap |
|
Decorator to transform a pymongo result object to a WriteOpResult object. |
|
Decorator to set key_fields and data_fields on a store. |
Classes
|
|
|
Extension of a dict wich triggers an event to notify the object that contains the dict that a modification has been made. |
|
Extension of a list wich triggers an event to notify the object that contains the list that a modification has been made. |
|
Base class to propagate a modification event through a parent-child chain structure. |
|
|
The shape of a normalized mongo write-operation result (see |
- class mongodol.trans.ObjOfData[source]#
Bases:
objectobj_of_data(value-only) transform functions forwrap_kvs.- static all_docs_fetch(cursor, doc_collector=<class 'list'>)[source]#
Collect every doc in
cursorintodoc_collector(default: a list).The value-only (
obj_of_data) counterpart ofPostGet.all_docs_fetch().
- class mongodol.trans.PersistentDict(container, wrapped_dict)[source]#
Bases:
dict,PersistentObjectBaseExtension of a dict wich triggers an event to notify the object that contains the dict that a modification has been made.
Requirement: The container object needs to implement the method “persist_data(self, data: Mapping)”.
>>> d = { ... 'a': 1, ... 'b': {'ba': 2, 'bb': 3}, ... 'c': [ ... {'c1a': 4, 'c1b': 5}, ... {'c2a': 6, 'c2b': '7'} ... ] ... } >>> class Container: ... def persist_data(self, data): ... """Here, you'd normally put code to ACTUALLY persist the data""" ... print(f"persisting {data}") >>> pd = PersistentDict(Container(), d) >>> pd['a'] = 8 persisting {'a': 8, 'b': {'ba': 2, 'bb': 3}, 'c': [{'c1a': 4, 'c1b': 5}, {'c2a': 6, 'c2b': '7'}]} >>> assert pd['a'] == 8 # and indeed pd['a'] is 8 now! >>> pd['b']['ba'] = 8 persisting {'a': 8, 'b': {'ba': 8, 'bb': 3}, 'c': [{'c1a': 4, 'c1b': 5}, {'c2a': 6, 'c2b': '7'}]} >>> assert pd['b']['ba'] == 8 # and indeed pd['b']['ba'] is 8 now! >>> pd['c'][0]['c1a'] = 8 persisting {'a': 8, 'b': {'ba': 8, 'bb': 3}, 'c': [{'c1a': 8, 'c1b': 5}, {'c2a': 6, 'c2b': '7'}]} >>> assert pd['c'][0]['c1a'] == 8 # and indeed pd['c'][0]['c1a'] is 8 now! >>> pd.update({'a': 9}) persisting {'a': 9, 'b': {'ba': 8, 'bb': 3}, 'c': [{'c1a': 8, 'c1b': 5}, {'c2a': 6, 'c2b': '7'}]} >>> assert pd['a'] == 9 >>> pd['b'].update({'ba': 9}) persisting {'a': 9, 'b': {'ba': 9, 'bb': 3}, 'c': [{'c1a': 8, 'c1b': 5}, {'c2a': 6, 'c2b': '7'}]} >>> assert pd['b']['ba'] == 9 >>> pd['c'][0].update({'c1a': 9}) persisting {'a': 9, 'b': {'ba': 9, 'bb': 3}, 'c': [{'c1a': 9, 'c1b': 5}, {'c2a': 6, 'c2b': '7'}]} >>> assert pd['c'][0]['c1a'] == 9 >>> pd.update([('a', 10)]) persisting {'a': 10, 'b': {'ba': 9, 'bb': 3}, 'c': [{'c1a': 9, 'c1b': 5}, {'c2a': 6, 'c2b': '7'}]} >>> assert pd['a'] == 10 >>> pd['b'].update([('ba', 10)]) persisting {'a': 10, 'b': {'ba': 10, 'bb': 3}, 'c': [{'c1a': 9, 'c1b': 5}, {'c2a': 6, 'c2b': '7'}]} >>> assert pd['b']['ba'] == 10 >>> pd['c'][0].update([('c1a', 10)]) persisting {'a': 10, 'b': {'ba': 10, 'bb': 3}, 'c': [{'c1a': 10, 'c1b': 5}, {'c2a': 6, 'c2b': '7'}]} >>> assert pd['c'][0]['c1a'] == 10 >>> del pd['a'] persisting {'b': {'ba': 10, 'bb': 3}, 'c': [{'c1a': 10, 'c1b': 5}, {'c2a': 6, 'c2b': '7'}]} >>> assert 'a' not in pd # indeed, 'a' no longer in pd >>> del pd['b']['ba'] persisting {'b': {'bb': 3}, 'c': [{'c1a': 10, 'c1b': 5}, {'c2a': 6, 'c2b': '7'}]} >>> assert 'ba' not in pd['b'] >>> del pd['c'][0]['c1a'] persisting {'b': {'bb': 3}, 'c': [{'c1b': 5}, {'c2a': 6, 'c2b': '7'}]} >>> assert 'c1a' not in pd['c'][0]
- class mongodol.trans.PersistentList(container, iterable)[source]#
Bases:
list,PersistentObjectBaseExtension of a list wich triggers an event to notify the object that contains the list that a modification has been made.
Requirement: The container object needs to implement the method “persist_data(self, data: Mapping)”.
>>> l = [1, 2, 3] >>> class Container: ... def persist_data(self, data): ... """Here, you'd normally put code to ACTUALLY persist the data""" ... print(f"persisting {data}") >>> pl = PersistentList(Container(), l) >>> assert pl == [1, 2, 3] # pl is equal to [1, 2, 3] >>> pl.append(4) persisting [1, 2, 3, 4] >>> assert pl == [1, 2, 3, 4] # indeed pl is now [1, 2, 3, 4] >>> pl.extend([5, 6]) persisting [1, 2, 3, 4, 5, 6] >>> assert pl == [1, 2, 3, 4, 5, 6] >>> pl += [7, 8] persisting [1, 2, 3, 4, 5, 6, 7, 8] >>> assert pl == [1, 2, 3, 4, 5, 6, 7, 8] >>> pl[0] = 9 persisting [9, 2, 3, 4, 5, 6, 7, 8] >>> assert pl == [9, 2, 3, 4, 5, 6, 7, 8] >>> n = pl.pop(0) persisting [2, 3, 4, 5, 6, 7, 8] >>> assert pl == [2, 3, 4, 5, 6, 7, 8] >>> pl.remove(2) persisting [3, 4, 5, 6, 7, 8] >>> assert pl == [3, 4, 5, 6, 7, 8] >>> del pl[0] persisting [4, 5, 6, 7, 8] >>> assert pl == [4, 5, 6, 7, 8]
- class mongodol.trans.PersistentObjectBase(container)[source]#
Bases:
ABCBase class to propagate a modification event through a parent-child chain structure.
- class mongodol.trans.PostGet[source]#
Bases:
objectpostget(key-aware) transform functions forwrap_kvs, turning a cursor into a value.- static all_docs_fetch(k, cursor, doc_collector=<class 'list'>)[source]#
Collect every doc matching
k, sos[k]is a collection of docs.The key-aware (
postget) counterpart ofObjOfData.all_docs_fetch().wrap_kvscallsobj_of_datawith the value alone andpostgetwith(key, value), so a store wired throughpostgetneeds this signature.
- class mongodol.trans.WriteOpResult[source]#
Bases:
TypedDictThe shape of a normalized mongo write-operation result (see
normalize_result).
- mongodol.trans.get_persistent_obj(container, v)[source]#
Wrap
vin aPersistentDict/PersistentListif it’s a mapping/iterable, else return it as is.
- mongodol.trans.normalize_result(obj, *, method_names_to_normalize=('__setitem__', '__delitem__', 'append', 'extend', 'flush', 'commit'))[source]#
Decorator to transform a pymongo result object to a WriteOpResult object.
- Parameters:
func ([type]) – [description]
- mongodol.trans.set_key_and_data_fields(store=None, *, key_fields=None, data_fields=None, __module__=None, __name__=None, __qualname__=None, __doc__=None, __annotations__=None, __defaults__=None, __kwdefaults__=None)[source]#
Decorator to set key_fields and data_fields on a store.
This is to make it easier to get from an interface like this
store[{'folder': 'path', 'file': 'name'}] = {'field1': 'value1', 'field2': 'value2'}to an interface like this:
store['path', 'name'] = ('value1', 'value2')