core.bones.relationalBone

Module Contents

Classes

RelationalConsistency

Generic enumeration.

relationalBone

This is our magic class implementing relations.

class core.bones.relationalBone.RelationalConsistency

Bases: enum.Enum

Generic enumeration.

Derive from this class to define new enumerations.

Ignore = 1
PreventDeletion = 2
SetNull = 3
CascadeDeletion = 4
class core.bones.relationalBone.relationalBone(kind: str = None, module: Optional[str] = None, refKeys: Optional[List[str]] = None, parentKeys: Optional[List[str]] = None, multiple: Union[bool, viur.core.bones.bone.MultipleConstraints] = False, format: str = "value['dest']['name']", using: Optional[viur.core.skeleton.RelSkel] = None, updateLevel: int = 0, consistency: RelationalConsistency = RelationalConsistency.Ignore, *args, **kwargs)

Bases: viur.core.bones.baseBone

This is our magic class implementing relations.

This implementation is read-efficient, e.g. filtering by relational-properties only costs an additional small-op for each entity returned. However, it costs several more write-ops for writing an entity to the db. (These costs are somewhat around additional (4+len(refKeys)+len(parentKeys)) write-ops for each referenced property) for multiple=True relationalBones and (4+len(refKeys)) for n:1 relations)

So don’t use this if you expect data being read less frequently than written! (Sorry, we don’t have a write-efficient method yet) To speedup writes to (maybe) referenced entities, information in these relations isn’t updated instantly. Once a skeleton is updated, a deferred task is kicked off which updates the references to that skeleton (if any). As a result, you might see stale data until this task has been finished.

Example:

  • Entity A references Entity B.

  • Both have a property “name”.

  • Entity B gets updated (it name changes).

  • As “A” has a copy of entity “B”s values, you’ll see “B”s old name inside the values of the relationalBone when fetching entity A.

If you filter a list by relational properties, this will also use the old data! (Eg. filtering A’s list by B’s new name won’t return any result)

refKeys = ['key', 'name']
parentKeys = ['key', 'name']
type = relational
kind
setSystemInitialized(self)
_getSkels(self)
singleValueUnserialize(self, val, skel: viur.core.skeleton.SkeletonInstance, name: str)

Restores one of our values (including the Rel- and Using-Skel) from the serialized data read from the datastore :param value: Json-Encoded datastore property :return: Our Value (with restored RelSkel and using-Skel)

serialize(self, skel: SkeletonInstance, name: str, parentIndexed: bool) bool
delete(self, skel: viur.core.skeleton.SkeletonInstance, name: str)

Ensure any outgoing relational lock is cleared

Parameters
  • skel

  • name

Returns

postSavedHandler(self, skel, boneName, key)
postDeletedHandler(self, skel, boneName, key)
isInvalid(self, key)
parseSubfieldsFromClient(self)
singleValueFromClient(self, value, skel, name, origData)
_rewriteQuery(self, name, skel, dbFilter, rawFilter)

Rewrites a datastore query to operate on “viur-relations” instead of the original kind. This is needed to perform relational queries on n:m relations.

buildDBFilter(self, name, skel, dbFilter, rawFilter, prefix=None)
buildDBSort(self, name, skel, dbFilter, rawFilter)
filterHook(self, name, query, param, value)

Hook installed by buildDbFilter. This rewrites all filters added to the query after buildDbFilter has been run to match the layout of our viur-relations index. Also performs sanity checks wherever this query is possible at all.

orderHook(self, name, query, orderings)

Hook installed by buildDbFilter. This rewrites all orderings added to the query after buildDbFilter has been run to match the layout of our viur-relations index. Also performs sanity checks wherever this query is possible at all.

refresh(self, skel, boneName)

Refresh all values we might have cached from other entities.

getSearchTags(self, skeletonValues, key)
getSearchDocumentFields(self, valuesCache, name, prefix='')

Generate fields for Google Search API

createRelSkelFromKey(self, key: Union[str, viur.core.db.KeyClass], rel: Union[dict, None] = None)

Creates a relSkel instance valid for this bone from the given database key.

setBoneValue(self, skel: SkeletonInstance, boneName: str, value: Any, append: bool, language: Union[None, str] = None) bool

Set our value to ‘value’. Santy-Checks are performed; if the value is invalid, no modification will happen.

Parameters
  • skel – Dictionary with the current values from the skeleton we belong to

  • 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.

getReferencedBlobs(self, skel, name)

Returns the list of blob keys referenced from this bone

getUniquePropertyIndexValues(self, valuesCache: dict, name: str) List[str]

By default, relationalBones distinct by referenced keys. Should be overridden if a different behaviour is required (eg. examine values from prop:usingSkel)