Rules / Maintenance

Ensure tables have relationships

info ENSURE_TABLES_HAVE_RELATIONSHIPS · ported · model layer · scope: Table, CalculatedTable

What it checks

Tables with no relationship to any other table. Calculation groups are not checked.

Each finding names the table, as 'Product'. A model with no relationships at all reports every table in it, one finding each.

Example

Fires the rule
table Sales
	column 'Product ID'
		dataType: int64
		sourceColumn: ProductID
	column Amount
		dataType: decimal
		sourceColumn: Amount

table Product
	column 'Product ID'
		dataType: int64
		isKey
		sourceColumn: ProductID
	column Category
		dataType: string
		sourceColumn: Category
After the fix
table Sales
	column 'Product ID'
		dataType: int64
		sourceColumn: ProductID
	column Amount
		dataType: decimal
		sourceColumn: Amount

table Product
	column 'Product ID'
		dataType: int64
		isKey
		sourceColumn: ProductID
	column Category
		dataType: string
		sourceColumn: Category

relationship Sales_Product
	fromColumn: Sales.'Product ID'
	toColumn: Product.'Product ID'

Why it matters

A table that relates to nothing filters nothing and is filtered by nothing, so a visual that mixes its columns with another table's shows the same value repeated on every row. Sometimes that is the point: a parameter table, a measure table, or a security lookup that is read from DAX. More often it is a table that was loaded and never wired up, or a relationship that was deleted by accident.

How to fix it

In Power BI Desktop, open Model view and drag the key column of the fact table onto the matching column of the dimension, or use Manage relationships, New, and pick the two columns. Check the cardinality and the cross filter direction that Desktop proposes before you accept them. In the TMDL file a relationship is a relationship block of its own, with fromColumn on the many side and toColumn on the one side, each written as Table.Column. If the table really does stand alone, leave it as it is.

When to ignore it

A table that is meant to stand alone is the case to ignore: a what-if parameter table, a field parameter table, a table of slicer labels that a measure reads with SELECTEDVALUE, a list of thresholds compared against measures, or a lookup table read only by a row-level security filter. Check that the table is one of those before you ignore the finding, because the same line appears when a relationship was dropped in a merge or when a rename left the relationship pointing at a table name that no longer exists.

To ignore this rule on one object, add annotation pbiplint.ignore = ENSURE_TABLES_HAVE_RELATIONSHIPS under the object in its TMDL file. Power BI Desktop keeps the annotation. To turn the rule off for a whole project, set "ENSURE_TABLES_HAVE_RELATIONSHIPS": "off" under rules in pbiplint.config.json.

Quirks

Ported from Microsoft's Best Practice Analyzer ruleset (opens in a new tab).

Check a model for this Improve this page (opens in a new tab)