Skip to main content

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:

License

This software is provided under the following license:

  • Apache Software License 2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jk_simpleobjpersistency-0.2021.1.18.tar.gz (10.2 kB view details)

Uploaded Source

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

Hashes for jk_simpleobjpersistency-0.2021.1.18.tar.gz
Algorithm Hash digest
SHA256 4c03bc426ced6416fd09d4c047b660585503042f15cc1c642ec9be6052a88920
MD5 c7ba76c571f53dd83266e0afb807e20b
BLAKE2b-256 512904d5330c79e63df658989eedcbf28dbb5c12a6ee66b4790260365ce4a4ae

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page