Skip to content

Chain

relationalai.semantics.frontend.base
Chain(
start: (
Chain
| Concept
| Relationship
| DerivedColumn
| Table
| Ref
| FieldRef
| Expression
),
next: Relationship,
is_ref=False,
)

Represents a chained relationship path created by attribute access.

Chain objects are produced when you access a relationship/property as a Python attribute on a DSL value (for example Person.name or Person.works_at.name). Calling a chain builds an Expression that you can use in Model.define and Model.where.

Most users should not instantiate this class directly.

Chain.__getattr__(item: str) -> Chain

Return a new chain by extending this path via attribute access.

Accessing an attribute on a Chain (for example Person.pets.name) returns another chain that represents following the current relationship path and then reading the relationship/property named by item.

Names that start with an underscore are treated as normal Python attribute access.

Parameters:

  • item

    (str) - Relationship/property name to access next.

Returns:

  • Chain - A chained value representing the extended relationship path.

Raises:

  • relationalai.util.error.RAIException - If the next relationship/property cannot be resolved (for example when the model.implicit_properties config flag is disabled).
Chain.__call__(*args: Any, **kwargs: Any) -> Expression

Return an expression by calling the next relationship in the chain.

Calling a Chain is shorthand for calling the underlying Relationship while implicitly supplying the chain’s start value as the first argument when you omit it (for example, alice.pets(boots) instead of pets(alice, boots)).

Parameters:

  • *args

    (Any, default: ()) - Positional arguments for the underlying relationship/property.
  • **kwargs

    (Any, default: {}) - Keyword field values passed through to the underlying call.

Returns:

Chain.__getitem__(field: str | int | Concept) -> FieldRef

Return a reference to one of the next relationship’s fields.

Indexing a Chain returns a FieldRef that identifies a specific field of the relationship at the end of the chain.

Parameters:

  • field

    (str | int | Concept) - Field selector: a 0-based index, an exact field name, or a field type (concept).

Returns:

  • FieldRef - A reference to the selected field.

Raises:

  • IndexError - If field is an integer index that is out of range.
  • KeyError - If no field matches the provided selector.
Chain.ref() -> Chain

Return an independent occurrence of this chain.

Use this when you need two separate matches of the same chain path (for example two different results from a multi-valued relationship). This does not introduce a new entity variable; it only makes this chain distinct from other identical paths.

Returns:

  • Chain - A chain treated as distinct from other identical chains.

Examples:

Select pairs of pets for the same person:

>>> from relationalai.semantics import Model, String
>>> m = Model()
>>> Person = m.Concept("Person")
>>> Person.pets = m.Relationship(f"{Person} has pet {String:pet_name}")
>>> m.define(alice := Person.new(name="Alice"), alice.pets("boots"), alice.pets("miso"))
>>> pet1, pet2 = alice.pets.ref(), alice.pets.ref()
>>> m.where(pet1 != pet2).select(pet1, pet2).to_df()

Referenced By:

RelationalAI Documentation
└──  Build With RelationalAI
    └──  Understand how PyRel works > Build a semantic model
        └──  Derive facts with logic
            └──  Match multiple related values with Chain.ref
Chain.alt(reading_str: str) -> Reading

Add an alternative reading for the relationship at the end of this chain.

This is a convenience wrapper around Relationship.alt that lets you call .alt(...) on a chained value (for example alice.pets). The reading is added to the underlying relationship, not to the chain’s start value.

Parameters:

Returns:

  • Reading - A relationship-like handle that renders using reading_str.
Chain.annotate(*annos: Expression | Relationship) -> Relationship

Attach one or more annotations to the relationship at the end of this chain.

This is a convenience wrapper around Relationship.annotate. Annotations are recorded on the underlying relationship and emitted into the compiled model. Annotations are primarily used by backends and internal tooling for debugging and support workflows (for example, to attach metadata such as tracking labels). In general you should not need to use annotations unless RelationalAI support instructs you to add them for diagnostic purposes.

Parameters:

Returns:

  • Relationship - The underlying relationship (returned to enable fluent chaining).

Raises:

  • relationalai.util.error.RAIException - Raised when an annotation argument has an unsupported type.
ChainVariableDSLBase
 semantics > frontend > base
├──  Concept
│   └──  identify_by
├──  Expression
└──  FieldRef
 semantics > frontend > base
├──  Chain
│   ├──  __getattr__
│   └──  ref
├──  Concept
│   └──  __getattr__
├──  Expression
│   └──  __getattr__
├──  Match
│   └──  __getattr__
├──  Ref
│   └──  __getattr__
└──  Table
    └──  __getitem__
RelationalAI Documentation
└──  Build With RelationalAI
    └──  Understand how PyRel works > Build a semantic model
        └──  Derive facts with logic
            ├──  Write conditional definitions with Model.where and Model.define
            └──  Match multiple related values with Chain.ref