fct_orders is a table model on Snowflake, and no constraints are declared on it. Consider its YAML. The model's SELECT list returns order_id, status, order_date, in that order, with matching data types. Which statement regarding dbt build --select fct_orders is true?
- The build succeeds; dbt logs a contract warning that the column order no longer matches.
- The build fails; the SELECT list must return columns in the order the YAML declares them.
- The build succeeds; the contract check compares column names and data types, not position.CORRECT
- The build succeeds; the created table's columns follow the model's SELECT order, and the YAML order is ignored.
WHY
An enforced contract makes dbt run a preflight check before the model is materialized: it gets the column names and data types the model's query will return, then compares that set against the columns declared in YAML. The comparison is done by column name — dbt fails the build only when a declared column is missing from the query, the query returns a column the contract does not declare, or a matched column's data_type differs, and it prints those rows in a mismatch table. Position in the SELECT list is not part of the compared shape, so reordering the same columns with the same types leaves the contract satisfied and the model builds. One related fact worth separating from the check itself, because it is easy to conflate: the ORDER of the columns in the table dbt creates does follow the contract. The docs say dbt "will include the column names, data types, and constraints in the DDL statements it submits to the data platform ... and order the columns per the contract instead of your dbt model." So the contract decides the physical column order of the built relation. The two facts sit either side of one line: order is not part of what the preflight check COMPARES, and it is entirely what the DDL FOLLOWS.
WHY THE OTHERS ARE WRONG
- The build succeeds; dbt logs a contract warning that the column order no longer matches.
- Contract enforcement is pass/fail at build time, not a warning channel — a violation raises an error and the model does not build. There is also no order-drift warning, because column order is never compared.
- The build fails; the SELECT list must return columns in the order the YAML declares them.
- Nothing in contract enforcement matches columns by ordinal position. dbt pairs each YAML column with the query's column of the same name, so a pure reorder produces no mismatch rows and no failure. (Ordering can matter when you hand-write DDL with constraints, but no constraints are declared here.)
- The build succeeds; the created table's columns follow the model's SELECT order, and the YAML order is ignored.
- This inverts the documented behaviour. The contract does not merely tolerate a different column order in your SELECT — it overrides it in the created table: dbt "will include the column names, data types, and constraints in the DDL statements it submits to the data platform ... and order the columns per the contract instead of your dbt model." So the YAML order is the one that survives into the relation, and the model's SELECT order is what gets ignored.