Skip to content

Fragment

relationalai.semantics.frontend.base
Fragment(model: Model, parent: Fragment | None = None)

Represents a composable query or rule fragment.

Fragments are returned by methods like Model.where and Model.select. You can chain Fragment.where, Fragment.select, Fragment.define, and Fragment.require, then materialize results with Fragment.to_df.

Fragments are built lazily: chaining methods builds up a query, but nothing runs until you materialize or execute it. Calling to_df() compiles the fragment and executes it to produce a pandas DataFrame. To export results into a table, call Fragment.into to specify the destination and then call Fragment.exec.

  • model

    (Model) - The model this fragment belongs to.
  • parent

    (Fragment, default: None) - Internal: parent fragment used to accumulate chained clauses.
>>> from relationalai.semantics import Integer, Model
>>> m = Model()
>>> Person = m.Concept("Person",)
>>> # A definition fragment that defines two people
>>> m.define(Person.new(name="Alice", age=10), Person.new(name="Bob", age=30))
>>> # A filter fragment that filters for people older than 21
>>> q = m.where(Person.age > 21)
>>> # A select fragment that extends the filter and selects the names of the filtered people
>>> q.select(Person.name)
>>> # Materialize the results as a DataFrame
>>> q.to_df()

Most users should not instantiate Fragment directly. Prefer starting from a Model (or the convenience functions where and select).

Fragment.where(*args: Statement) -> Fragment

Return a new fragment with additional filter conditions.

Unlike Model.where, this extends an existing Fragment. Multiple conditions are combined with AND.

Parameters:

Returns:

  • Fragment - A composable fragment representing the combined filter(s).

Referenced By:

RelationalAI Documentation
└──  Build With RelationalAI
    └──  Understand how PyRel works > Build a semantic model
        └──  Derive facts with logic
            ├──  Understand PyRel logic constructs
            └──  Write conditional definitions with Model.where and Model.define
Fragment.select(*args: StatementAndSchema) -> Fragment

Return a new fragment with selected outputs.

Unlike Model.select, this extends an existing Fragment. Passing a TableSchema expands to selecting each column of the table. Selecting a comparison expression like x > y produces a boolean output column.

Parameters:

Returns:

  • Fragment - A composable fragment representing the combined selection.

Referenced By:

RelationalAI Documentation
└──  Build With RelationalAI
    └──  Understand how PyRel works > Build a semantic model
        └──  Derive facts with logic
            └──  Understand PyRel logic constructs
Fragment.require(*args: Statement) -> Fragment

Return a new fragment with additional requirements.

Unlike Model.require, this extends an existing Fragment. A requirement is an existence check (it fails when there are no matches). Scope a requirement with Fragment.where to express per-entity constraints.

Parameters:

Returns:

  • Fragment - A composable fragment representing the combined requirement(s).

Referenced By:

RelationalAI Documentation
└──  Build With RelationalAI
    └──  Understand how PyRel works > Build a semantic model
        └──  Define requirements
            ├──  How a requirement works
            └──  Add a scoped requirement with Model.where
Fragment.define(*args: Statement) -> Fragment

Return a new fragment with additional definitions.

Unlike Model.define, this extends an existing Fragment. It is most commonly used to write conditional definitions by chaining where(...).define(...).

Parameters:

Returns:

  • Fragment - A composable fragment representing the combined definition(s).

Referenced By:

RelationalAI Documentation
└──  Build With RelationalAI
    └──  Understand how PyRel works > Build a semantic model
        └──  Derive facts with logic
            ├──  Understand PyRel logic constructs
            └──  Write conditional definitions with Model.where and Model.define
Fragment.meta(**kwargs: Any) -> Fragment

Attach execution metadata to this fragment.

The provided keyword arguments are forwarded as meta=... when the fragment is executed (for example via Fragment.exec or Fragment.to_df). This does not change the query’s semantics; it only annotates the execution request. This is useful for tagging runs with context like a request id, job name, or other tracing/debugging information.

Parameters:

  • **kwargs

    (Any, default: {}) - Metadata key/value pairs to attach.

Returns:

  • Fragment - This fragment, to allow chaining.
Fragment.annotate(*annos: Expression | Relationship) -> Fragment

Attach one or more annotations to this fragment.

An annotation is recorded on the fragment and emitted into the compiled query or rule. 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:

  • Fragment - This fragment (returned to enable fluent chaining).

Raises:

  • relationalai.util.error.RAIException - Raised when an annotation argument has an unsupported type.
Fragment.into(table: Table, update=False) -> Fragment

Return a new fragment configured to export results into a table.

Call this on a query fragment (typically after select(...)) to set the export destination, then execute it with Fragment.exec.

Parameters:

  • table

    (Table) - Destination table reference.
  • update

    (bool, default: False) - If True, perform an update export (backend-dependent) rather than replacing the destination.

Returns:

  • Fragment - A new fragment that will export to table when executed.

Referenced By:

RelationalAI Documentation
└──  Build With RelationalAI
    └──  Understand how PyRel works > Build a semantic model
        ├──  Overview
        │   └──  What you can do after the model is built
        ├──  Derive facts with logic
        │   └──  Understand PyRel logic constructs
        └──  Query a model
            ├──  Understand fragments and materialization
            └──  Export results to Snowflake tables with into and exec
Fragment.exec()

Execute this fragment and export results into the table set by Fragment.into.

Calling exec() runs the query once; subsequent calls are a no-op. Use Fragment.to_df to execute without exporting.

Returns:

  • pandas.DataFrame | None - The query results as a DataFrame, or None if the fragment was already executed.

Raises:

  • relationalai.util.error.RAIException - If no destination table was specified via Fragment.into.

Notes:

Exporting query results does not avoid materializing results in Python, since the executor returns the results as a pandas DataFrame. This can have performance implications, especially for large result sets.

Referenced By:

RelationalAI Documentation
└──  Build With RelationalAI
    └──  Understand how PyRel works > Build a semantic model
        ├──  Overview
        │   └──  What you can do after the model is built
        └──  Query a model
            ├──  Understand fragments and materialization
            └──  Export results to Snowflake tables with into and exec
Fragment.to_df()

Materialize this fragment as a pandas DataFrame.

Calling to_df() compiles the fragment and executes it, returning the query results as a DataFrame.

Returns:

  • pandas.DataFrame - The query results.

Notes:

to_df executes the query and materializes the full result in memory. This can have performance implications, especially for large result sets.

Referenced By:

RelationalAI Documentation
└──  Build With RelationalAI
    └──  Understand how PyRel works > Build a semantic model
        ├──  Derive facts with logic
        │   └──  Understand PyRel logic constructs
        └──  Query a model
            ├──  Understand fragments and materialization
            └──  Materialize results with to_df
Fragment.__or__(other) -> Match

Return a match expression (self | other).

Use | to express fallback/default behavior between two query branches (for example, a selected value or a default literal). The returned Match evaluates branches left-to-right and picks the first branch that can succeed for the current bindings.

This is commonly used with fragments to provide defaults for optional subqueries that may have no match.

Parameters:

Returns:

  • Match - A composable match expression.

Examples:

Use a default when an optional lookup has no match:

>>> from relationalai.semantics import Model
>>> m = Model()
>>> User = m.Concept("User")
>>> m.define(
... User.new(id=1, name="Alice", status="active"),
... User.new(id=2, name="Bob", status="inactive"),
... User.new(id=3, name="Carol"),
... )
>>> status = m.select(User.status) | "unknown"
>>> m.where(User.id.in_([2, 3])).select(User.name, status).to_df()
Fragment.__and__(other) -> Fragment

Combine two filter fragments with AND (self & other).

This operator is only supported for where-only fragments (fragments that contain only where(...) clauses). If other is not already a Fragment, it is treated as a single filter condition and wrapped as Fragment(self._model).where(other).

Parameters:

Returns:

  • Fragment - A new where-only fragment with the combined conditions.

Raises:

  • Exception - Raised when either side is not a where-only fragment.

Examples:

Combine an existing filter fragment with an additional condition:

>>> from relationalai.semantics import Model
>>> m = Model()
>>> Person = m.Concept("Person")
>>> m.define(
... Person.new(name="Alice", age=10),
... Person.new(name="Bob", age=30)
... )
>>> people_over_40 = m.where(Person.age > 40)
>>> people_named_bob = m.where(Person.name == "Bob")
>>> q = people_over_40 & people_named_bob
>>> q.select(Person.name).to_df()
FragmentDerivedTableVariableDSLBase
 semantics > frontend > base
└──  Concept
    └──  require
.
├──  agent > cortex
│   ├──  queries
│   │   ├──  Queries
│   │   │   └──  execute
│   │   └──  QueryCatalog
│   │       └──  execute
│   └──  tool
│       └──  Tool
│           └──  query
└──  semantics
    ├──  frontend > base
    │   ├──  Concept
    │   │   └──  require
    │   ├──  Fragment
    │   │   ├──  __and__
    │   │   ├──  annotate
    │   │   ├──  define
    │   │   ├──  into
    │   │   ├──  meta
    │   │   ├──  require
    │   │   ├──  select
    │   │   └──  where
    │   ├──  Model
    │   │   ├──  define
    │   │   ├──  require
    │   │   ├──  select
    │   │   └──  where
    │   ├──  Not
    │   │   └──  __and__
    │   └──  Variable
    │       └──  __and__
    ├──  std > constraints
    │   └──  oneof
    ├──  define
    ├──  require
    ├──  select
    └──  where
RelationalAI Documentation
└──  Build With RelationalAI
    └──  Understand how PyRel works
        ├──  Configure PyRel
        │   └──  Configure execution behavior
        ├──  Build a semantic model
        │   ├──  Overview
        │   │   └──  What you can do after the model is built
        │   ├──  Derive facts with logic
        │   │   ├──  Understand PyRel logic constructs
        │   │   └──  Write conditional definitions with Model.where and Model.define
        │   ├──  Define requirements
        │   │   ├──  How a requirement works
        │   │   └──  Add a scoped requirement with Model.where
        │   └──  Query a model
        │       ├──  Understand fragments and materialization
        │       ├──  Materialize results with to_df
        │       └──  Export results to Snowflake tables with into and exec
        └──  Use advanced reasoning > Rules-based reasoning
            └──  Aggregate and group data
                └──  Scope aggregate inputs with aggregate-local .where()