Skip to main content
A relationship is a join between two models in the same dataset: it links a column on a from model to a column on a to model with a cardinality (oneToOne, oneToMany, or manyToOne). Relationships let metric columns aggregate across related records and let queries traverse from one model to another. You define one in code with defineRelationship.

Define a relationship

Wire each side to a model by handle, so both models deploy before the relationship and their uuids are injected automatically:
relationships/contact-account.ts
import { defineRelationship } from "@cargo-ai/cdk";
import { accounts } from "../models/accounts";
import { contacts } from "../models/contacts";

export const contactAccount = defineRelationship("contact-account", {
  from: { model: contacts, column: "account_id" },
  to: { model: accounts, column: "id" },
  relation: "manyToOne",
});
FieldRole
fromThe referencing side — { model, column }. model is a model handle or modelRef(uuid); column is the slug holding the foreign key.
toThe referenced side — { model, column }, typically the target’s identifier column (e.g. id).
relationCardinality: oneToOne, oneToMany, or manyToOne.
from.property / to.propertyOptional. Navigate into a JSON (object / array) column value, e.g. "hubspot___companies[0]". Only valid on JSON-typed columns.
Both models must live in the same dataset — the dataset is derived from the from model at deploy. Relationships have no server-side slug, so the defineRelationship slug is a local identifier only; the deployed relationship is tracked by its state uuid.
A defineRelationship only manages the row it declares — relationships you create in the UI or by other means on the same dataset are left untouched. On destroy, only the managed relationship is removed.

From the CLI

Relationships are set per dataset as a JSON array. List the datasets to find the datasetUuid, then set one or more relationships:
cargo-ai storage dataset list                     # → datasetUuid
cargo-ai storage relationship list                # existing relationships

cargo-ai storage relationship set \
  --dataset-uuid <datasetUuid> \
  --relationships '[{"fromModelUuid":"<contacts-uuid>","fromColumnSlug":"account_id","toModelUuid":"<accounts-uuid>","toColumnSlug":"id","relation":"manyToOne"}]'
relationship set is a per-dataset replace: the payload becomes the full set of manually-managed relationships for that dataset, so include every relationship you want to keep. (Auto-generated unification relationships are managed separately and aren’t affected.)

Next steps

Models overview

How relationships fit alongside a model’s columns and segments.

Object models

Link native Account / Contact / Deal records to each other.

Querying data

Join related models with SQL in your warehouse.

Deploying

The reconcile lifecycle that creates and updates relationships.