core.skeleton

Module Contents

Classes

MetaBaseSkel

This is the meta class for Skeletons.

SkeletonInstance

The actual wrapper around a Skeleton-Class. An object of this class is what's actually returned when you

BaseSkeleton

This is a container-object holding information about one database entity.

MetaSkel

This is the meta class for Skeletons.

CustomDatabaseAdapter

ViurTagsSearchAdapter

This Adapter implements a simple fulltext search on top of the datastore.

seoKeyBone

Skeleton

This is a container-object holding information about one database entity.

RelSkel

This is a Skeleton-like class that acts as a container for Skeletons used as a

RefSkel

This is a Skeleton-like class that acts as a container for Skeletons used as a

SkelList

This class is used to hold multiple skeletons together with other, commonly used information.

TaskUpdateSearchIndex

This tasks loads and saves every entity of the given module.

RebuildSearchIndex

TaskVacuumRelations

Checks entries in viur-relations and verifies that the src-kind and it's relational-bone still exists.

Functions

skeletonByKind(→ Type[Skeleton])

Returns the Skeleton-Class for the given kindName. That skeleton must exist, otherwise an exception is raised.

listKnownSkeletons(→ List[str])

return:

A list of all known kindnames (all kindnames for which a skeleton is defined)

iterAllSkelClasses(→ Iterable[Skeleton])

return:

An iterator that yields each Skeleton-Class once. (Only top-level skeletons are returned, so no

processRemovedRelations(removedKey[, cursor])

updateRelations(destKey, minChangeTime, changedBone[, ...])

This function updates Entities, which may have a copy of values from another entity which has been recently

processVacuumRelationsChunk(module, cursor[, ...])

Processes 100 Entries and calls the next batch

Attributes

pytz

__undefindedC__

core.skeleton.pytz
core.skeleton.__undefindedC__
class core.skeleton.MetaBaseSkel(name, bases, dct)

Bases: type

This is the meta class for Skeletons. It is used to enforce several restrictions on bone names, etc.

_skelCache
_allSkelClasses
__reserved_keywords
core.skeleton.skeletonByKind(kindName: str) Type[Skeleton]

Returns the Skeleton-Class for the given kindName. That skeleton must exist, otherwise an exception is raised. :param kindName: The kindname to retreive the skeleton for :return: The skeleton-class for that kind

core.skeleton.listKnownSkeletons() List[str]
Returns:

A list of all known kindnames (all kindnames for which a skeleton is defined)

core.skeleton.iterAllSkelClasses() Iterable[Skeleton]
Returns:

An iterator that yields each Skeleton-Class once. (Only top-level skeletons are returned, so no RefSkel classes will be included)

class core.skeleton.SkeletonInstance(skelCls, subSkelNames=None, fullClone=False, clonedBoneMap=None)

The actual wrapper around a Skeleton-Class. An object of this class is what’s actually returned when you call a Skeleton-Class. With ViUR3, you don’t get an instance of a Skeleton-Class any more - it’s always this class. This is much faster as this is a small class.

__slots__
items(yieldBoneValues: bool = False) Iterable[Tuple[str, viur.core.bones.BaseBone]]
keys() Iterable[str]
values() Iterable[Any]
__iter__() Iterable[str]
__contains__(item)
get(item, default=None)
__setitem__(key, value)
__getitem__(key)
__getattr__(item)
__delattr__(item)

Implement delattr(self, name).

__setattr__(key, value)

Implement setattr(self, name, value).

__repr__() str

Return repr(self).

__str__() str

Return str(self).

__len__() int
clone()
setEntity(entity: viur.core.db.Entity)
__deepcopy__(memodict)
class core.skeleton.BaseSkeleton

Bases: object

This is a container-object holding information about one database entity.

It has to be sub-classed with individual information about the kindName of the entities and its specific data attributes, the so called bones. The Skeleton stores its bones in an OrderedDict-Instance, so the definition order of the contained bones remains constant.

Variables:
  • key (server.bones.BaseBone) – This bone stores the current database key of this entity. Assigning to this bones value is dangerous and does not affect the actual key its stored in.

  • creationdate (server.bones.DateBone) – The date and time where this entity has been created.

  • changedate (server.bones.DateBone) – The date and time of the last change to this entity.

__viurBaseSkeletonMarker__ = True
boneMap
classmethod subSkel(*name, fullClone: bool = False, **kwargs) SkeletonInstance

Creates a new sub-skeleton as part of the current skeleton.

A sub-skeleton is a copy of the original skeleton, containing only a subset of its bones. To define sub-skeletons, use the subSkels property of the Skeleton object.

By passing multiple sub-skeleton names to this function, a sub-skeleton with the union of all bones of the specified sub-skeletons is returned.

If an entry called “*” exists in the subSkels-dictionary, the bones listed in this entry will always be part of the generated sub-skeleton.

Parameters:

name – Name of the sub-skeleton (that’s the key of the subSkels dictionary); Multiple names can be specified.

Returns:

The sub-skeleton of the specified type.

classmethod setSystemInitialized()
classmethod setBoneValue(skelValues: Any, boneName: str, value: Any, append: bool = False, language: str | None = None) bool

Allow setting a bones value without calling fromClient or assigning to valuesCache directly. Santy-Checks are performed; if the value is invalid, that bone flips back to its original (default) value and false is returned.

Parameters:
  • boneName – The Bone which should be modified

  • value – The value that should be assigned. It’s type depends on the type of that bone

  • append – If true, the given value is appended to the values of that bone instead of replacing it. Only supported on bones with multiple=True

  • language – Set/append which language

Returns:

Wherever that operation succeeded or not.

classmethod fromClient(skelValues: SkeletonInstance, data: Dict[str, List[str] | str], allowEmptyRequired=False) bool

Load supplied data into Skeleton.

This function works similar to setValues(), except that the values retrieved from data are checked against the bones and their validity checks.

Even if this function returns False, all bones are guaranteed to be in a valid state. The ones which have been read correctly are set to their valid values; Bones with invalid values are set back to a safe default (None in most cases). So its possible to call toDB() afterwards even if reading data with this function failed (through this might violates the assumed consistency-model).

Parameters:

data – Dictionary from which the data is read.

Returns:

True if all data was successfully read and taken by the Skeleton’s bones. False otherwise (eg. some required fields where missing or invalid).

classmethod refresh(skel: SkeletonInstance)

Refresh the bones current content.

This function causes a refresh of all relational bones and their associated information.

class core.skeleton.MetaSkel(name, bases, dct)

Bases: MetaBaseSkel

This is the meta class for Skeletons. It is used to enforce several restrictions on bone names, etc.

class core.skeleton.CustomDatabaseAdapter
providesFulltextSearch: bool = False
fulltextSearchGuaranteesQueryConstrains = False
providesCustomQueries: bool = False
preprocessEntry(entry: viur.core.db.Entity, skel: BaseSkeleton, changeList: List[str], isAdd: bool) viur.core.db.Entity

Can be overridden to add or alter the data of this entry before it’s written to firestore. Will always be called inside an transaction. :param entry: The entry containing the serialized data of that skeleton :param skel: The (complete) skeleton this skel.toDB() runs for :param changeList: List of boneNames that are changed by this skel.toDB() call :param isAdd: Is this an update or an add? :return: The (maybe modified) entity

updateEntry(dbObj: viur.core.db.Entity, skel: BaseSkeleton, changeList: List[str], isAdd: bool) None

Like meth:preprocessEntry, but runs after the transaction had completed. Changes made to dbObj will be ignored. :param entry: The entry containing the serialized data of that skeleton :param skel: The (complete) skeleton this skel.toDB() runs for :param changeList: List of boneNames that are changed by this skel.toDB() call :param isAdd: Is this an update or an add?

deleteEntry(entry: viur.core.db.Entity, skel: BaseSkeleton) None

Called, after an skeleton has been successfully deleted from firestore :param entry: The db.Entity object containing an snapshot of the data that has been deleted :param skel: The (complete) skeleton for which `meth:delete’ had been called

abstract fulltextSearch(queryString: str, databaseQuery: viur.core.db.Query) List[viur.core.db.Entity]

If this database supports fulltext searches, this method has to implement them. If it’s a plain fulltext search engine, leave ‘prop:fulltextSearchGuaranteesQueryConstrains’ set to False, then the server will post-process the list of entries returned from this function and drop any entry that cannot be returned due to other constrains set in ‘param:databaseQuery’. If you can obey every constrain set in that Query, we can skip this post-processing and save some CPU-cycles. :param queryString: the string as received from the user (no quotation or other safety checks applied!) :param databaseQuery: The query containing any constrains that returned entries must also match :return:

class core.skeleton.ViurTagsSearchAdapter(min_length: int = 3, max_length: int = 99, substring_matching: bool = True)

Bases: CustomDatabaseAdapter

This Adapter implements a simple fulltext search on top of the datastore.

On skel.toDB(), all words from String-/TextBones are collected with all min_length postfixes and dumped into the property viurTags. When queried, we’ll run a prefix-match against this property - thus returning entities with either an exact match or a match within a word.

Example:

For the word “hello” we’ll write “hello”, “ello” and “llo” into viurTags. When queried with “hello” we’ll have an exact match. When queried with “hel” we’ll match the prefix for “hello” When queried with “ell” we’ll prefix-match “ello” - this is only enabled when substring_matching is True.

We’ll automatically add this adapter if a skeleton has no other database adapter defined.

providesFulltextSearch = True
fulltextSearchGuaranteesQueryConstrains = True
_tagsFromString(value: str) Set[str]

Extract all words including all min_length postfixes from given string

preprocessEntry(entry: viur.core.db.Entity, skel: Skeleton, changeList: List[str], isAdd: bool) viur.core.db.Entity

Collect searchTags from skeleton and build viurTags

fulltextSearch(queryString: str, databaseQuery: viur.core.db.Query) List[viur.core.db.Entity]

Run a fulltext search

class core.skeleton.seoKeyBone

Bases: viur.core.bones.StringBone

unserialize(skel: viur.core.skeleton.SkeletonInstance, name: str) bool
serialize(skel: SkeletonInstance, name: str, parentIndexed: bool) bool
class core.skeleton.Skeleton(*args, **kwargs)

Bases: BaseSkeleton

This is a container-object holding information about one database entity.

It has to be sub-classed with individual information about the kindName of the entities and its specific data attributes, the so called bones. The Skeleton stores its bones in an OrderedDict-Instance, so the definition order of the contained bones remains constant.

Variables:
  • key (server.bones.BaseBone) – This bone stores the current database key of this entity. Assigning to this bones value is dangerous and does not affect the actual key its stored in.

  • creationdate (server.bones.DateBone) – The date and time where this entity has been created.

  • changedate (server.bones.DateBone) – The date and time of the last change to this entity.

kindName: str
customDatabaseAdapter: CustomDatabaseAdapter | None
subSkels
interBoneValidations: List[Callable[[Skeleton], List[viur.core.bones.base.ReadFromClientError]]] = []
key
creationdate
changedate
viurCurrentSeoKeys
__repr__()

Return repr(self).

__str__()

Return str(self).

classmethod all(skelValues, **kwargs) viur.core.db.Query

Create a query with the current Skeletons kindName.

Returns:

A db.Query object which allows for entity filtering and sorting.

classmethod fromClient(skelValues: SkeletonInstance, data: Dict[str, List[str] | str], allowEmptyRequired=False) bool

This function works similar to setValues(), except that the values retrieved from data are checked against the bones and their validity checks.

Even if this function returns False, all bones are guaranteed to be in a valid state. The ones which have been read correctly are set to their valid values; Bones with invalid values are set back to a safe default (None in most cases). So its possible to call toDB() afterwards even if reading data with this function failed (through this might violates the assumed consistency-model).

Parameters:

data – Dictionary from which the data is read.

Returns:

True, if all values have been read correctly (without errors), False otherwise

classmethod fromDB(skelValues: SkeletonInstance, key: str | viur.core.db.Key) bool

Load entity with key from the data store into the Skeleton.

Reads all available data of entity kind kindName and the key key from the data store into the Skeleton structure’s bones. Any previous data of the bones will discard.

To store a Skeleton object to the data store, see toDB().

Parameters:

key – A viur.core.DB.Key, viur.core.DB.Query, or string, from which the data shall be fetched.

Returns:

True on success; False if the given key could not be found.

classmethod toDB(skelValues: SkeletonInstance, clearUpdateTag: bool = False) viur.core.db.Key

Store current Skeleton entity to data store.

Stores the current data of this instance into the database. If an key value is set to the object, this entity will ne updated; Otherwise an new entity will be created.

To read a Skeleton object from the data store, see fromDB().

Parameters:

clearUpdateTag – If True, this entity won’t be marked dirty; This avoids from being fetched by the background task updating relations.

Returns:

The datastore key of the entity.

classmethod preProcessBlobLocks(skelValues, locks)

Can be overridden to modify the list of blobs referenced by this skeleton

classmethod preProcessSerializedData(skelValues, entity)

Can be overridden to modify the viur.core.db.Entity before its actually written to the data store.

classmethod postSavedHandler(skelValues, key, dbObj)

Can be overridden to perform further actions after the entity has been written to the data store.

classmethod postDeletedHandler(skelValues, key)

Can be overridden to perform further actions after the entity has been deleted from the data store.

classmethod getCurrentSEOKeys(skelValues) None | Dict[str, str]

Should be overridden to return a dictionary of language -> SEO-Friendly key this entry should be reachable under. How theses names are derived are entirely up to the application. If the name is already in use for this module, the server will automatically append some random string to make it unique. :return:

classmethod delete(skelValues)

Deletes the entity associated with the current Skeleton from the data store.

class core.skeleton.RelSkel

Bases: BaseSkeleton

This is a Skeleton-like class that acts as a container for Skeletons used as a additional information data skeleton for extendedRelationalBone.

It needs to be sub-classed where information about the kindName and its attributes (bones) are specified.

The Skeleton stores its bones in an OrderedDict-Instance, so the definition order of the contained bones remains constant.

classmethod fromClient(skelValues: SkeletonInstance, data: Dict[str, List[str] | str], allowEmptyRequired=False) bool

Reads the data supplied by data. Unlike setValues, error-checking is performed. The values might be in a different representation than the one used in getValues/serValues. Even if this function returns False, all bones are guranteed to be in a valid state: The ones which have been read correctly contain their data; the other ones are set back to a safe default (None in most cases) So its possible to call save() afterwards even if reading data fromClient faild (through this might violates the assumed consitency-model!).

Parameters:

data – Dictionary from which the data is read

Returns:

True if the data was successfully read; False otherwise (eg. some required fields where missing or invalid)

serialize(parentIndexed)
unserialize(values: viur.core.db.Entity | dict)

Loads ‘values’ into this skeleton.

Parameters:

values – dict with values we’ll assign to our bones

class core.skeleton.RefSkel

Bases: RelSkel

This is a Skeleton-like class that acts as a container for Skeletons used as a additional information data skeleton for extendedRelationalBone.

It needs to be sub-classed where information about the kindName and its attributes (bones) are specified.

The Skeleton stores its bones in an OrderedDict-Instance, so the definition order of the contained bones remains constant.

classmethod fromSkel(kindName: str, *args: List[str]) Type[RefSkel]

Creates a relSkel from a skeleton-class using only the bones explicitly named in *args

Parameters:

args – List of bone names we’ll adapt

Returns:

A new instance of RefSkel

class core.skeleton.SkelList(baseSkel=None)

Bases: list

This class is used to hold multiple skeletons together with other, commonly used information.

SkelLists are returned by Skel().all()…fetch()-constructs and provide additional information about the data base query, for fetching additional entries.

Variables:

cursor (str) – Holds the cursor within a query.

__slots__ = ['baseSkel', 'getCursor', 'customQueryInfo', 'renderPreparation']
core.skeleton.processRemovedRelations(removedKey, cursor=None)
core.skeleton.updateRelations(destKey: viur.core.db.Key, minChangeTime: int, changedBone: str | None, cursor: str | None = None)

This function updates Entities, which may have a copy of values from another entity which has been recently edited (updated). In ViUR, relations are implemented by copying the values from the referenced entity into the entity that’s referencing them. This allows ViUR to run queries over properties of referenced entities and prevents additional db.Get’s to these referenced entities if the main entity is read. However, this forces us to track changes made to entities as we might have to update these mirrored values. This is the deferred call from meth:viur.core.skeleton.Skeleton.toDB() after an update (edit) on one Entity to do exactly that.

Parameters:
  • destKey – The database-key of the entity that has been edited

  • minChangeTime – The timestamp on which the edit occurred. As we run deferred, and the entity might have been edited multiple times before we get acutally called, we can ignore entities that have been updated in the meantime as they’re already up2date

  • changedBone – If set, we’ll update only entites that have a copy of that bone. Relations mirror only key and name by default, so we don’t have to update these if only another bone has been changed.

  • cursor – The database cursor for the current request as we only process five entities at once and then defer again.

class core.skeleton.TaskUpdateSearchIndex

Bases: viur.core.tasks.CallableTaskBase

This tasks loads and saves every entity of the given module. This ensures an updated searchIndex and verifies consistency of this data.

key = 'rebuildSearchIndex'
name = 'Rebuild search index'
descr = 'This task can be called to update search indexes and relational information.'
canCall() bool

Checks wherever the current user can execute this task

dataSkel()
execute(module, *args, **kwargs)
static _run(module: str, notify: str)
class core.skeleton.RebuildSearchIndex

Bases: viur.core.tasks.QueryIter

classmethod handleEntry(skel: SkeletonInstance, customData: Dict[str, str])
classmethod handleFinish(totalCount: int, customData: Dict[str, str])
class core.skeleton.TaskVacuumRelations

Bases: viur.core.tasks.CallableTaskBase

Checks entries in viur-relations and verifies that the src-kind and it’s relational-bone still exists.

key = 'vacuumRelations'
name = 'Vacuum viur-relations (dangerous)'
descr = 'Drop stale inbound relations for the given kind'
canCall() bool

Checks wherever the current user can execute this task :returns: bool

dataSkel()
execute(module, *args, **kwargs)
core.skeleton.processVacuumRelationsChunk(module, cursor, allCount=0, removedCount=0, notify=None)

Processes 100 Entries and calls the next batch