Skip to content

type_bridge.generator.render.relations

relations

Render relation class definitions from parsed schema.

RelationContext dataclass

RelationContext(class_name, base_class, docstring, flags_args, attr_fields=list(), role_fields=list(), cascade_attrs=list(), subkey_groups=dict(), distinct_roles=list(), annotations=dict())

Context for rendering a single relation class.

render_relations

render_relations(schema, attr_class_names, entity_class_names, relation_class_names=None)

Render the complete relations module source.

Parameters:

Name Type Description Default
schema ParsedSchema

Parsed schema containing relation definitions

required
attr_class_names dict[str, str]

Mapping from TypeDB attr names to Python class names

required
entity_class_names dict[str, str]

Mapping from TypeDB entity names to Python class names

required
relation_class_names dict[str, str] | None

Mapping from TypeDB relation names to Python class names

None

Returns:

Type Description
str

Complete Python source code for relations.py

Source code in type_bridge/generator/render/relations.py
def render_relations(
    schema: ParsedSchema,
    attr_class_names: dict[str, str],
    entity_class_names: dict[str, str],
    relation_class_names: dict[str, str] | None = None,
) -> str:
    """Render the complete relations module source.

    Args:
        schema: Parsed schema containing relation definitions
        attr_class_names: Mapping from TypeDB attr names to Python class names
        entity_class_names: Mapping from TypeDB entity names to Python class names
        relation_class_names: Mapping from TypeDB relation names to Python class names

    Returns:
        Complete Python source code for relations.py
    """
    logger.debug(f"Rendering {len(schema.relations)} relation classes")
    if relation_class_names is None:
        relation_class_names = {name: to_class_name(name) for name in schema.relations}

    # Build imports list
    imports = ["Relation", "Role", "TypeFlags"]
    # Flag is needed for @key, @unique, or multi-value attributes (Card used with Flag)
    needs_flag = (
        _needs_key_import(schema)
        or _needs_unique_import(schema)
        or _needs_card_for_attributes(schema)
    )
    if _needs_card_import(schema):
        imports.insert(0, "Card")
    if needs_flag:
        imports.insert(0, "Flag")
    if _needs_key_import(schema):
        imports.append("Key")
    if _needs_unique_import(schema):
        imports.append("Unique")

    relations = []
    all_names = []
    for relation_name in _topological_sort_relations(schema):
        all_names.append(relation_class_names[relation_name])
        relations.append(
            _build_relation_context(
                relation_name,
                schema,
                attr_class_names,
                entity_class_names,
                relation_class_names,
            )
        )

    template = get_template("relations.py.jinja")
    result = template.render(
        imports=imports,
        relations=relations,
        all_names=sorted(all_names),
    )

    logger.info(f"Rendered {len(all_names)} relation classes")
    return result