type_bridge.crud.utils¶
utils
¶
Shared utilities for CRUD operations.
This module re-exports functions from focused submodules for convenience. You can also import directly from the submodules:
- type_bridge.crud.formatting: format_value, unwrap_attribute
- type_bridge.crud.patterns: build_entity_match_pattern, build_relation_match_pattern, normalize_role_players
- type_bridge.crud.types: is_multi_value_attribute, hydrate_attributes, etc.
- type_bridge.crud.role_players: Role player utilities
format_value
¶
Format a Python value for TypeQL.
Handles extraction from Attribute instances and converts Python types to their TypeQL literal representation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
Any
|
Python value to format (may be wrapped in Attribute instance) |
required |
Returns:
| Type | Description |
|---|---|
str
|
TypeQL-formatted string literal |
Examples:
>>> format_value("hello")
'"hello"'
>>> format_value(42)
'42'
>>> format_value(True)
'true'
>>> format_value(Decimal("123.45"))
'123.45dec'
Source code in type_bridge/crud/formatting.py
unwrap_attribute
¶
Extract raw value from Attribute instance.
This utility consolidates the common pattern of extracting the underlying value from Attribute instances before processing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
Any
|
Value that may be an Attribute instance or raw value |
required |
Returns:
| Type | Description |
|---|---|
Any
|
The raw value (value.value if Attribute, otherwise value unchanged) |
Examples:
>>> unwrap_attribute(Name("Alice"))
"Alice"
>>> unwrap_attribute("Alice")
"Alice"
>>> unwrap_attribute(42)
42
Source code in type_bridge/crud/formatting.py
build_entity_match_pattern
¶
Build a TypeQL match pattern for an entity.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model_class
|
type[Entity]
|
The entity model class |
required |
var
|
str
|
Variable name to use (default: "$e") |
'$e'
|
filters
|
dict[str, Any] | None
|
Attribute filters as field_name -> value |
None
|
Returns:
| Type | Description |
|---|---|
str
|
TypeQL match pattern string like "$e isa person, has name "Alice"" |
Examples:
Source code in type_bridge/crud/patterns.py
build_relation_match_pattern
¶
Build a TypeQL match pattern for a relation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model_class
|
type[Relation]
|
The relation model class |
required |
var
|
str
|
Variable name to use (default: "$r") |
'$r'
|
role_players
|
dict[str, str] | None
|
Dict mapping role names to player variable names |
None
|
Returns:
| Type | Description |
|---|---|
str
|
TypeQL match pattern string |
Raises:
| Type | Description |
|---|---|
ValueError
|
If a role name is not defined in the model |
Examples:
>>> build_relation_match_pattern(Employment, role_players={"employee": "$p"})
'$r isa employment, (employee: $p)'
Source code in type_bridge/crud/patterns.py
normalize_role_players
¶
Normalize role players to always be lists for uniform handling.
Handles both single entities and lists of entities (for multi-cardinality roles). Also generates unique variable names for each player in the match clause.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
role_players
|
dict[str, Any]
|
Dict mapping role_name -> entity or list of entities |
required |
Returns:
| Type | Description |
|---|---|
dict[str, list[Any]]
|
Tuple of: |
dict[str, list[str]]
|
|
tuple[dict[str, list[Any]], dict[str, list[str]]]
|
|
Examples:
>>> normalize_role_players({"employee": alice, "employer": company})
({"employee": [alice], "employer": [company]},
{"employee": ["employee"], "employer": ["employer"]})
>>> normalize_role_players({"member": [alice, bob]})
({"member": [alice, bob]},
{"member": ["member_0", "member_1"]})
Source code in type_bridge/crud/patterns.py
build_role_player_fetch_items
¶
Build fetch items for role players with their IIDs and type labels.
TypeQL 3.x doesn't allow mixing iid() with .* in the same nested block, so we fetch the IID as a separate key alongside the nested attributes. We also fetch the type label to correctly identify polymorphic role players.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
role_info
|
dict[str, tuple[str, Any]]
|
Dict mapping role_name -> (role_var, allowed_entity_types) |
required |
Returns:
| Type | Description |
|---|---|
list[str]
|
List of fetch item strings like: '"employee_iid": iid($employee)' '"employee_type": label($employee_type)' '"employee": { $employee.* }' |
The caller must add type variable bindings to the match clause:
$employee isa $employee_type;
Source code in type_bridge/crud/role_players.py
build_role_player_match
¶
Build a match clause for a role player entity.
Prefers IID-based matching when available (more precise and faster), falls back to key attribute matching, and raises a clear error if neither is available.
Used by TypeDBManager for relation CRUD operations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
var_name
|
str
|
The variable name to use (without $) |
required |
entity
|
Any
|
The entity instance |
required |
entity_type_name
|
str
|
The TypeDB type name for the entity |
required |
Returns:
| Type | Description |
|---|---|
str
|
A TypeQL match clause string like "$var_name isa type, iid 0x..." |
str
|
or "$var_name isa type, has key_attr value" |
Raises:
| Type | Description |
|---|---|
ValueError
|
If entity has neither _iid nor key attributes |
Source code in type_bridge/crud/role_players.py
extract_relation_attributes
¶
Extract relation attributes from a query result.
Uses the unified wrap_attribute_value() helper for consistent handling of multi-value and single-value attributes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model_class
|
type[Relation]
|
The relation class to extract attributes for |
required |
result
|
dict[str, Any]
|
The result dictionary from TypeDB fetch |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Dictionary mapping field_name -> attribute value (ready for model constructor) |
Source code in type_bridge/crud/role_players.py
extract_role_players_from_results
¶
Extract and deduplicate role players from grouped query results.
For multi-player roles, collects all unique players from all rows in the group. For single-player roles, takes the first player found.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
result_group
|
list[dict[str, Any]]
|
List of result rows with the same relation IID |
required |
role_info
|
dict[str, tuple[str, tuple[type[Entity], ...]]]
|
Dict mapping role_name -> (role_var, allowed_entity_classes) |
required |
multi_player_roles
|
set[str]
|
Set of role names that allow multiple players |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Dictionary mapping role_name -> player entity or list of player entities |
Source code in type_bridge/crud/role_players.py
group_results_by_iid
¶
Group query results by relation/entity IID.
TypeDB returns one row per role player combination for multi-cardinality roles. This utility groups those rows by IID so they can be merged into a single relation instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
results
|
list[dict[str, Any]]
|
List of result dictionaries from TypeDB fetch |
required |
Returns:
| Type | Description |
|---|---|
dict[str, list[dict[str, Any]]]
|
Dictionary mapping IID -> list of result rows with that IID |
Source code in type_bridge/crud/role_players.py
resolve_entity_class_from_label
¶
Resolve the correct Python entity class from a TypeDB type label.
This is a thin wrapper around ModelRegistry.resolve() that provides polymorphic class resolution with caching.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
type_label
|
str | None
|
The TypeDB type label (from label() function), e.g., "person" |
required |
allowed_entity_classes
|
tuple[type[Entity], ...]
|
Tuple of allowed entity classes for this role |
required |
Returns:
| Type | Description |
|---|---|
type[Entity]
|
The matching Python entity class, or the first allowed class as fallback |
Source code in type_bridge/crud/role_players.py
build_metadata_fetch
¶
Build a fetch clause that retrieves only IID and type metadata.
Uses TypeQL 3.8.0 built-in functions iid() and label() to fetch the internal ID and type label. This is used for queries that need to identify entities/relations without fetching all attributes.
Note: TypeQL grammar doesn't allow mixing "key": value entries with $e.* in the same fetch clause, so metadata-only fetch is separate from attribute fetch.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
var
|
str
|
Variable name (with or without $) |
required |
Returns:
| Type | Description |
|---|---|
str
|
Fetch clause string like 'fetch { "_iid": iid($e), "_type": label($e) }' |
Example
build_metadata_fetch("e") 'fetch {\n "_iid": iid($e), "_type": label($e)\n}'
Source code in type_bridge/crud/types.py
extract_entity_key
¶
Extract the first key attribute from an entity for matching.
This is used to build match clauses based on key attributes when IID is not available.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
entity
|
Any
|
The entity instance |
required |
Returns:
| Type | Description |
|---|---|
tuple[str, str, Any] | None
|
Tuple of (field_name, attr_typeql_name, raw_value) if a key attribute |
tuple[str, str, Any] | None
|
with a non-None value is found, otherwise None. |
Examples:
Source code in type_bridge/crud/types.py
hydrate_attributes
¶
Hydrate attributes from TypeDB fetch result.
Extracts attribute values from a raw TypeDB result dictionary, mapping TypeDB attribute names to Python field names. Handles multi-value attributes and collects key values for deduplication.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
entity_class
|
type[Entity]
|
The entity class to extract attributes for |
required |
raw_data
|
dict[str, Any]
|
Raw attribute data from TypeDB fetch result |
required |
wrap_values
|
bool
|
If True, wrap attributes in Attribute instances using the unified wrap_attribute_value() helper |
False
|
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Tuple of (attrs_dict, key_values_tuple): |
tuple[tuple[str, Any], ...]
|
|
tuple[dict[str, Any], tuple[tuple[str, Any], ...]]
|
|
Examples:
>>> result = {"name": "Alice", "age": 30}
>>> attrs, keys = hydrate_attributes(Person, result)
>>> attrs
{"name": "Alice", "age": 30}
>>> keys
(("name", "Alice"),) # if name is a key attribute
Source code in type_bridge/crud/types.py
is_multi_value_attribute
¶
Check if attribute is multi-value based on cardinality.
Multi-value attributes have either: - Unbounded cardinality (card_max is None) - Maximum cardinality > 1
Single-value attributes have: - Maximum cardinality == 1 (including 0..1 and 1..1)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
flags
|
AttributeFlags
|
AttributeFlags instance containing cardinality information |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if multi-value (card_max is None or > 1), False if single-value |
Examples:
>>> flags = AttributeFlags(card_min=0, card_max=1)
>>> is_multi_value_attribute(flags)
False
>>> flags = AttributeFlags(card_min=0, card_max=5)
>>> is_multi_value_attribute(flags)
True
>>> flags = AttributeFlags(card_min=2, card_max=None)
>>> is_multi_value_attribute(flags)
True