Skip to content

How can I create a unique constraint on a skeleton over multiple bones? #1256

@sveneberth

Description

@sveneberth

I have these bones in a Skeleton:

name = StringBone(
)

module = SelectBone(
    values=lambda: {name: name for name in ModuleConf.MODULES},
)

Now I want to ensure there's at least one skeleton per permutation of the values:

for example

{name: "foo", module: "file", other_bone:"abc"}  # id: 1
{name: "bar", module: "file", other_bone:"456"}  # id: 2
{name: "foo", module: "user", other_bone:"abc"}  # id: 3
{name: "bar", module: "user", other_bone:"abc"}  # id: 4

can exist together.
But you should not able to add

{name: "foo", module: "file", other_bone: "def"}  # id: 5

because there's already an entry (ìd: 1) with {name: "foo", module: "file"}.

I tried to create a composition of these bones with a compute bone.

    unique_lock = StringBone(
        compute=Compute(lambda skel: f'{skel["module"]}_{skel["name"]}',
                        interval=ComputeInterval(ComputeMethod.OnWrite)),
        visible=False,
        unique=UniqueValue(UniqueLockMethod.SameValue, False, "Value already taken"),
    )

But this doesn't cause a client-error in fromClient and fails only in the skeleton toDB transaction:

  File "/.../lib/python3.11/site-packages/viur/core/skeleton.py", line 1029, in __txn_update
    raise ValueError(
ValueError: The unique value 'file_foo' of bone 'unique_lock' has been recently claimed!

Does anyone has an idea how I can simplify this / enforce a client error?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Priority: HighAfter critical issues are fixed, these should be dealt with before any further issues.help wantedExtra attention is neededquestionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions