Skip to navigation

Define Relationships

View as Markdown

Relationships connect foreign keys in event or junction tables to primary keys in entity tables. Kumo Relational uses these relationships to sample relational context for a prediction.

Continue with the schema and table metadata configured on the preceding pages.

Inspect inferred relationships

Schema.from_data() infers relationships by matching a column to a primary key of the same name — deliberately conservative, since a wrong link changes what the model is shown and is harder to notice than a missing one. Schema.from_source() prefers the foreign-key constraints the catalog declares, and falls back to the same name-matching inference where it declares none. Inspect the result before running predictions:

print(schema.relationships)

For the customers, orders, and products example, confirm that the schema contains the following relationships:

Source tableForeign keyTarget tableTarget key
orderscustomer_idcustomerscustomer_id
ordersproduct_idproductsproduct_id

Correct a relationship

Relationship is a plain dataclass. If inference misses a relationship, add it explicitly:

from sdm_client import Relationship
schema.relationships.append(
Relationship(
source_table="orders",
source_column="customer_id",
target_table="customers",
target_column="customer_id",
)
)

If inference creates an incorrect relationship, remove it before adding the intended one:

schema.relationships = [
link for link in schema.relationships
if not (link.source_table == "orders" and link.source_column == "customer_id"
and link.target_table == "products")
]
schema.relationships.append(
Relationship("orders", "customer_id", "customers", "customer_id")
)

Use consistent primary-key and foreign-key names whenever possible. For example, prefer customer_id in both customers and orders instead of mixing names such as id, customer_id, and account_id for the same entity — a name shared by more than one table’s primary key is ambiguous and links nothing.

Composite relationships are supported. A composite foreign key must reference the full composite primary key, with corresponding columns supplied in the same order and with compatible physical types:

schema["customers"].primary_key = ("customer_id", "region")
schema.relationships.append(
Relationship(
source_table="orders",
source_column=("customer_id", "region"),
target_table="customers",
target_column=("customer_id", "region"),
)
)

A relationship can only point at a table’s declared primary key, and a table with a composite key can only be the target of a relationship whose source columns match it component for component.

For a schema built over a semantic model (source.semantic_model(...)), passing relationships= to from_source() replaces the model’s own joins rather than adding to them. To keep the model’s relationships and add one more, read schema.relationships after building and append to it, as shown above, rather than passing relationships= to from_source().

Model one-to-many relationships

Kumo Relational schema relationships represent primary-key-to-foreign-key relationships. The target table contains the unique primary key, and the source table can contain that foreign-key value across multiple rows.

For many-to-many relationships, prepare a junction table that converts the relationship into two one-to-many relationships. For example, an order_items table can relate orders and products through order_id and product_id. Refer to Data Preparation Best Practices for the junction-table pattern.

Relationship checklist

  • Every foreign key points to the intended entity table.
  • The referenced target column is that table’s primary key.
  • Source and target key values use compatible physical types.
  • Each relationship has business meaning, rather than merely sharing a column name.
  • The schema contains the paths needed by the predictive queries you plan to run.

After making corrections, inspect the relationships again:

print(schema.relationships)

Next, check the complete schema.