Chain
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.
Parameters
Section titled “Parameters”
(startChain|Concept|Relationship|DerivedColumn|Table|Ref|FieldRef|Expression) - Root value for the chain (for example aConcept,Ref, or another chain).
(nextRelationship) - Relationship/property to apply next.
(is_refbool, default:False) - If True, mark the chain as a reference.
Most users should not instantiate this class directly.
Methods
Section titled “Methods”.__getattr__()
Section titled “.__getattr__()”Chain.__getattr__(item: str) -> ChainReturn 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:
(itemstr) - 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 themodel.implicit_propertiesconfig flag is disabled).
.__call__()
Section titled “.__call__()”Chain.__call__(*args: Any, **kwargs: Any) -> ExpressionReturn 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:
(*argsAny, default:()) - Positional arguments for the underlying relationship/property.
(**kwargsAny, default:{}) - Keyword field values passed through to the underlying call.
Returns:
Expression- A composable expression that can be used inModel.defineandModel.where.
.__getitem__()
Section titled “.__getitem__()”Chain.__getitem__(field: str | int | Concept) -> FieldRefReturn 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:
(fieldstr|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- Iffieldis an integer index that is out of range.KeyError- If no field matches the provided selector.
.ref()
Section titled “.ref()”Chain.ref() -> ChainReturn 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.alt()
Section titled “.alt()”Chain.alt(reading_str: str) -> ReadingAdd 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:
(reading_strstr) - Reading string passed through toRelationship.alt.
Returns:
Reading- A relationship-like handle that renders usingreading_str.
.annotate()
Section titled “.annotate()”Chain.annotate(*annos: Expression | Relationship) -> RelationshipAttach 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:
(*annosExpression|Relationship, default:()) - One or more annotation nodes to attach.
Returns:
Relationship- The underlying relationship (returned to enable fluent chaining).
Raises:
relationalai.util.error.RAIException- Raised when an annotation argument has an unsupported type.
Inheritance Hierarchy
Section titled “Inheritance Hierarchy”Used By
Section titled “Used By”semantics > frontend > base ├── Concept │ └── identify_by ├── Expression └── FieldRef
Returned By
Section titled “Returned By”semantics > frontend > base ├── Chain │ ├── __getattr__ │ └── ref ├── Concept │ └── __getattr__ ├── Expression │ └── __getattr__ ├── Match │ └── __getattr__ ├── Ref │ └── __getattr__ └── Table └── __getitem__
Referenced By
Section titled “Referenced By”RelationalAI Documentation └── Build With RelationalAI └── Understand how PyRel works > Build a semantic model └── Derive facts with logic ├── Write conditional definitions withModel.whereandModel.define└── Match multiple related values withChain.ref