This python module provides a simple persistency for data objects.
Project description
jk_simpleobjpersistency
Introduction
This python module provides a simple persistency for data objects.
Information about this module can be found here:
How to use this module
Import package
To import the package jk_simpleobjpersistency
use the following code:
import jk_simpleobjpersistency
Implement a class usable for persistency
If you want to persist an object you have to consider a few minor aspects for your implementation:
- Your constructor must be parameterless.
- You require to implement a regular object method deserializing from a dictionary:
deserialize(self, dataObj:dict)
- You require to implement a regular object method serializing to a dictionary:
serialize(self) -> dict
- You must not use any of these member identifiers:
setChanged
,store
,storeIfChanged
,isModified
,destroy
,isNew
,isPersistent
as well as_x_isModified
._x_persisteer
,_x_identifier
,_x_isAutoStore
.
That's it.
A quite minimum implementation of a serializing class might then look like this:
class MyUserObj(object):
def __init__(self):
self.userName = None
self.password = None
self.eMail = None
self.yearOfBirth = None
def deserialize(self, jData:dict):
self.userName = jData.get("userName")
self.password = jData.get("password")
self.eMail = jData.get("eMail")
self.yearOfBirth = jData.get("yearOfBirth")
def serialize(self):
return {
"userName": self.userName,
"password": self.password,
"eMail": self.eMail,
"yearOfBirth": self.yearOfBirth,
}
This is just an example but it demonstrates the basic concept. Here: The object variables will hold the object's data, and the methods deserialize()
and serialize()
will be used by the framework to implement persistency.
For persistency to work the class and the objects will be patched by the persistency framework. Additional methods are added: setChanged
, store
, storeIfChanged
, isModified
, destroy
, isNew
, isPersistent
as well as _x_isModified
. _x_persisteer
, _x_identifier
, _x_isAutoStore
. This is the reason why you must not use the specific identifiers listed above. (If you do they will get overridden by the framework and your implementation will likely break.)
Instantiate and initialize the persistency layer
In order to work with this persistency layer you need a) to instantiate a persistency data manager first and b) register all classes that should be persistent before then c) working with instances of these classes.
The most recommended way for isntantiation is something like this:
pm = jk_simpleobjpersistency.PersistencyManager("/my/data/dir/path")
The path argument is the root directory where data is stored (if not specified otherwise during registration of a class).
After that you must register all classes that the persistency layer should deal with. This is done invoking registerClass()
for each class persistency should be active for.
A class registration requires the following arguments:
Argument name | Argument typ | Required or optional | Description |
---|---|---|---|
clazz |
A class type | required | The class itself |
defaults |
dict or an instance of the serialization type |
optional | Either the serialized data or an prototypical instance of the class type (that get serialized by invoking serialize() |
dirPath |
str |
optional | The directory to store the data. (By default the class name is used.) |
autoStore |
bool |
optional | If true modified objects get stored automatically on delete if they have been changed. (Default: false ) |
Example:
ppdm = jk_simpleobjpersistency.PersistencyManager("testdata")
ppdm.registerClass(
clazz=MyUserObj,
defaults={
"eMail": "example@example.com"
},
dirPath="testdata/users",
autoStore=True)
As you can see in this example we use a dictionary for the defaults. The content of the dictionary must match expectations of the class implementation.
Creating instances
An instance of an object can be created like this:
obj = pp.createObject(MyUserObj, "myUser")
That's it. obj
now contains a fresh instance of MyUserObj
.
But let's have a look at the arguments:
Argument name | Argument typ | Required or optional | Description |
---|---|---|---|
clazz |
A class type | required | The class itself |
identifier |
str |
optional | If specified an instance is created that furtheron will be uniquely identified by this string. If no identifier is specified, a new one is generated. |
Please note that the object will not have been stored yet. If you throw it away without storing - and autoStore
is not True
- then data you might have put into the object will be lost.
Modifying instances
You have two options:
- Either using the modified-flag that is provided by every instance or
- store every modified object explicitely.
Example:
obj = pp.createObject(MyUserObj, "myUser")
obj.userName = "something"
obj.password = "somepwd123"
obj.store()
Or:
obj = pp.createObject(MyUserObj, "myUser")
obj.userName = "something"
obj.password = "somepwd123"
obj.setModified()
And later on invoke obj.storeIfModified()
. (This storing is performed automatically if autoStore
is set to True
during registration of a class.
CAUTION! Be aware that at the end of your program all objects should be stored already. Python defines no order in how objects get disposed: It might well be that
build in functions like open()
used for writing a file might be disposed already at the time a modified object tries to store itself. It's remains your reponsibility
as programmer to take care that all objects have been properly saved when your program terminates. (Compare: https://stackoverflow.com/questions/23422188/why-am-i-getting-nameerror-global-name-open-is-not-defined-in-del) Have a look at storeAllModified(clazz)
which might
help you in this case.
Destroying an instance
Instances can be destroyed by invoking destroy()
on the persistent object itself. Please be aware that this action is immediate: If data is persistently stored on disk this
data is removed instantly.
Example:
obj = pp.getObject(MyUserObj, "myUser")
obj.destroy()
A note about caching
All objects created or retrieved from backgroud storage are cached. That means that these objects consume memory. If this is a problem you can invoke any of these methods at any time:
Method | Description |
---|---|
clearEntireCache() |
That will remove all cached intances. |
clearClassCache(clazz) |
Clear the cache for a specific class. |
Contact Information
This is Open Source code. That not only gives you the possibility of freely using this code it also allows you to contribute. Feel free to contact the author(s) of this software listed below, either for comments, collaboration requests, suggestions for improvement or reporting bugs:
- Jürgen Knauth: pubsrc@binary-overflow.de
License
This software is provided under the following license:
- Apache Software License 2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file jk_simpleobjpersistency-0.2021.1.18.tar.gz
.
File metadata
- Download URL: jk_simpleobjpersistency-0.2021.1.18.tar.gz
- Upload date:
- Size: 10.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.14.0 pkginfo/1.4.2 requests/2.20.1 setuptools/40.6.3 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/3.5.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 4c03bc426ced6416fd09d4c047b660585503042f15cc1c642ec9be6052a88920 |
|
MD5 | c7ba76c571f53dd83266e0afb807e20b |
|
BLAKE2b-256 | 512904d5330c79e63df658989eedcbf28dbb5c12a6ee66b4790260365ce4a4ae |