Skip to main content

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:

License

This software is provided under the following license:

  • Apache Software License 2.0

Metadata

Release files for jk-simpleobjpersistency 0.2021.1.18

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

Source distribution (sdist)

Source distribution for jk-simpleobjpersistency 0.2021.1.18
File Size Uploaded
jk_simpleobjpersistency-0.2021.1.18.tar.gz 10.2 kB Details

Release files / jk_simpleobjpersistency-0.2021.1.18.tar.gz

Download URL jk_simpleobjpersistency-0.2021.1.18.tar.gz
Size 10.2 kB
Tags Source
SHA-256 checksum
How to use checksums
4c03bc426ced6416fd09d4c047b660585503042f15cc1c642ec9be6052a88920
BLAKE2b-256 checksum
How to use checksums
512904d5330c79e63df658989eedcbf28dbb5c12a6ee66b4790260365ce4a4ae
Upload date
Uploaded using Trusted Publishing?
What is 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

Release history Release notifications | RSS feed

This release

0.2021.1.18 This release

1 release file

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