### Example usage of config_meta_get and config_meta_require
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/09-internal-helpers.md
Example usage of the compatibility macros. `config_meta_get` retrieves a value with a default, while `config_meta_require` raises a compiler error if the key is missing.
```jinja
{%- set period = automate_dv.config_meta_get('period', default='day') -%}
{%- set rank_column = automate_dv.config_meta_require('rank_column') -%}
```
--------------------------------
### ma_sat basic call example
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/02-tables-satellites.md
A basic usage example of the ma_sat macro with a single child key.
```sql
{{ config(materialized='incremental', unique_key='HK_LINK_ACCOUNT_HOLDER') }}
{%- set src_pk = 'HK_LINK_ACCOUNT_HOLDER' -%}
{%- set src_cdk = 'ACCOUNT_HOLDER' -%}
{%- set src_hashdiff = 'HASHDIFF' -%}
{%- set src_payload = ['HOLDER_NAME', 'HOLDER_DOB'] -%}
{%- set src_ldts = 'LOAD_DATETIME' -%}
{%- set src_source = 'RECORD_SOURCE' -%}
{%- set source_model = 'stage_account_holder' -%}
{{ automate_dv.ma_sat(src_pk=src_pk, src_cdk=src_cdk,
src_hashdiff=src_hashdiff, src_payload=src_payload,
src_ldts=src_ldts, src_source=src_source,
source_model=source_model) }}
```
--------------------------------
### nh_link basic call example
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/03-tables-other.md
Example of calling automate_dv.nh_link with a basic configuration, using an incremental materialization and a unique key. Sets source parameters and invokes the macro.
```sql
{{ config(materialized='incremental', unique_key='HK_NH_LINK_ACCOUNT') }}
{%- set src_pk = 'HK_NH_LINK_ACCOUNT' -%}
{%- set src_fk = 'ACCOUNT_FK' -%}
{%- set src_payload = ['ACCOUNT_BALANCE', 'ACCOUNT_STATUS'] -%}
{%- set src_ldts = 'LOAD_DATETIME' -%}
{%- set src_source = 'RECORD_SOURCE' -%}
{%- set source_model = 'stage_account' -%}
{{ automate_dv.nh_link(src_pk=src_pk, src_fk=src_fk,
src_payload=src_payload,
src_ldts=src_ldts, src_source=src_source,
source_model=source_model) }}
```
--------------------------------
### multikey usage example
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/08-metadata-processing.md
Example usage of the multikey macro with two columns and two prefixes, rendering an equality predicate. The comment shows the expected output.
```jinja
{{ automate_dv.multikey(['HK_A', 'HK_B'], prefix=['src', 'tgt'], condition='=') }}
-- renders: src.HK_A = tgt.HK_A AND src.HK_B = tgt.HK_B
```
--------------------------------
### ma_sat composite child key example
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/02-tables-satellites.md
An example of using ma_sat where the child key (src_cdk) is provided as a list for a composite key.
```sql
{{ config(materialized='incremental', unique_key='HK_LINK_ACCOUNT_HOLDER') }}
{%- set src_pk = 'HK_LINK_ACCOUNT_HOLDER' -%}
{%- set src_cdk = ['HOLDER_ROLE', 'HOLDER_SINCE'] -%}
{%- set src_hashdiff = 'HASHDIFF' -%}
{%- set src_payload = ['HOLDER_COMMENT'] -%}
{%- set src_ldts = 'LOAD_DATETIME' -%}
{%- set src_source = 'RECORD_SOURCE' -%}
{%- set source_model = 'stage_account_holder' -%}
{{ automate_dv.ma_sat(src_pk=src_pk, src_cdk=src_cdk,
src_hashdiff=src_hashdiff, src_payload=src_payload,
src_ldts=src_ldts, src_source=src_source,
source_model=source_model) }}
```
--------------------------------
### prefix macro usage example
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/06-hash-prefix-casting.md
Example usage of the `prefix` macro with a list of columns and an alias. Renders a comma-separated list of `alias.column` references.
```sql
{{ automate_dv.prefix(['HK_HUB_CUSTOMER', 'LOAD_DATETIME'], 'rr') }}
-- renders: rr.HK_HUB_CUSTOMER, rr.LOAD_DATETIME
```
--------------------------------
### Basic hash call example
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/06-hash-prefix-casting.md
Example of calling the `hash` macro with a single column and alias. This produces a hashed column expression for a hub key.
```sql
{{ automate_dv.hash(columns=['CUSTOMER_ID'], alias='HK_HUB_CUSTOMER') }}
```
--------------------------------
### Single-step bridge walk example
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/03-tables-other.md
Example configuration for a single-step bridge walk using the `bridge` macro. It sets up the required variables (`src_pk`, `as_of_dates_table`, `src_ldts`, `source_model`, `bridge_walk`, `stage_tables_ldts`) and calls `automate_dv.bridge` with keyword arguments. The `bridge_walk` mapping defines a single link-eff-sat pair.
```sql
{{ config(materialized='bridge_incremental') }}
{%- set src_pk = 'CUSTOMER_ID' -%}
{%- set as_of_dates_table = 'as_of_date' -%}
{%- set src_ldts = 'LOAD_DATETIME' -%}
{%- set source_model = 'hub_customer' -%}
{%- set bridge_walk = {
'link_customer_product': {
'link_table': 'link_customer_product',
'link_pk': 'HK_LINK_CUSTOMER_PRODUCT',
'link_fk1': 'HK_CUSTOMER',
'link_fk2': 'HK_PRODUCT',
'eff_sat_table': 'eff_sat_customer_product',
'eff_sat_pk': 'HK_LINK_CUSTOMER_PRODUCT',
'eff_sat_load_date': 'LOAD_DATETIME',
'eff_sat_end_date': 'END_DATE',
'bridge_link_pk': 'HK_LINK_CUSTOMER_PRODUCT',
'bridge_end_date': 'BRIDGE_END_DATE',
'bridge_load_date': 'BRIDGE_LOAD_DATE'
}
} -%}
{%- set stage_tables_ldts = {'stage_customer_product': 'LOAD_DATETIME'} -%}
{{ automate_dv.bridge(src_pk=src_pk, as_of_dates_table=as_of_dates_table,
bridge_walk=bridge_walk,
stage_tables_ldts=stage_tables_ldts,
src_ldts=src_ldts, source_model=source_model) }}
```
--------------------------------
### Basic call to `automate_dv.pit`
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/03-tables-other.md
SQL example of a basic PIT table configuration, showing how to set up the necessary variables and call the macro.
```sql
{{ config(materialized='pit_incremental') }}
{%- set src_pk = 'CUSTOMER_ID' -%}
{%- set as_of_dates_table = 'as_of_date' -%}
{%- set src_ldts = 'LOAD_DATETIME' -%}
{%- set source_model = 'hub_customer' -%}
{%- set satellites = {
'sat_customer': {
'pk': {'CUSTOMER_PK': 'HK_HUB_CUSTOMER'},
'ldts': {'CUSTOMER_LDTS': 'LOAD_DATETIME'}
}
} -%}
{%- set stage_tables_ldts = {'stage_customer': 'LOAD_DATETIME'} -%}
{{ automate_dv.pit(src_pk=src_pk, as_of_dates_table=as_of_dates_table,
satellites=satellites,
stage_tables_ldts=stage_tables_ldts,
src_ldts=src_ldts, source_model=source_model) }}
```
--------------------------------
### concat_ws usage example
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/08-metadata-processing.md
Example usage of the concat_ws macro. It renders a CONCAT_WS SQL expression with the given separator.
```jinja
{{ automate_dv.concat_ws(["UPPER(TRIM(col1))", "UPPER(TRIM(col2))"], '||') }}
```
--------------------------------
### Hashdiff hash call example
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/06-hash-prefix-casting.md
Example of calling the `hash` macro with `is_hashdiff=true` to sort columns before hashing. Use this for hashdiff columns.
```sql
{{ automate_dv.hash(columns=['CUSTOMER_NAME', 'CUSTOMER_DOB', 'CUSTOMER_EMAIL'],
alias='HASHDIFF',
is_hashdiff=true) }}
```
--------------------------------
### Example call to create_ghost_record in a satellite model
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/07-ghost-records.md
Example of calling create_ghost_record inside a satellite model. Sets up variables for PK, hashdiff, payload, load timestamp, source, and source model, then invokes the macro. The model is configured as incremental.
```sql
{{ config(materialized='incremental') }}
{%- set src_pk = 'HK_HUB_CUSTOMER' -%}
{%- set src_hashdiff = 'HASHDIFF' -%}
{%- set src_payload = ['CUSTOMER_NAME', 'CUSTOMER_EMAIL'] -%}
{%- set src_ldts = 'LOAD_DATETIME' -%}
{%- set src_source = 'RECORD_SOURCE' -%}
{%- set source_model = 'stage_customer' -%}
{{ automate_dv.create_ghost_record(src_pk=src_pk, src_hashdiff=src_hashdiff,
src_payload=src_payload,
src_ldts=src_ldts, src_source=src_source,
source_model=source_model) }}
```
--------------------------------
### automate_dv.hub
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/01-tables-hub-link.md
Documentation for the `automate_dv.hub` macro, including signatures, parameters, return type, and usage examples.
```APIDOC
## automate_dv.hub
### Description
Builds a Data Vault Hub (business key table). Deduplicates the source by business key (`src_nk`), keeping the first row per key ordered by load date (`src_ldts`); when `source_model` is a list, sources are unioned, then re-deduplicated across the union. Supports the `vault_insert_by_period`, `vault_insert_by_rank` and standard incremental materializations via the `__PERIOD_FILTER__` / `__RANK_FILTER__` placeholders.
### Signature (dispatcher)
```jinja
{%- macro hub(src_pk, src_nk, src_extra_columns, src_ldts, src_source, source_model) -%}
```
### Signature (default implementation)
```jinja
{%- macro default__hub(src_pk, src_nk, src_extra_columns, src_ldts, src_source, source_model) -%}
```
### Parameters
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `src_pk` | string or list[string] | yes | — | Hub surrogate key column(s) (hash key). Passed to `check_required_parameters`; `None` raises a compiler error. |
| `src_nk` | string or list[string] | yes | — | Natural business key column(s) |
| `src_extra_columns` | string or list[string] | no | — | Additional columns to carry through (e.g. `src_eff`, `src_cdk`) |
| `src_ldts` | string | yes | — | Load date/timestamp column |
| `src_source` | string | yes | — | Record source column |
| `source_model` | string or list[string] / mapping | yes | — | Source model name(s); scalar is wrapped into a list internally |
### Return Type
Renders a `WITH row_rank_N AS (…), [stage_union AS (…)], [stage_mat_filter AS (…)], [row_rank_union AS (…)], records_to_insert AS (…) SELECT * FROM records_to_insert` CTE chain. The final `records_to_insert` LEFT JOINs `this` (de-duplicating drops already-loaded hubs) **only when `automate_dv.is_any_incremental()`** evaluates true; otherwise it is a full-select pattern.
### Throws
Compiler error from `check_required_parameters` when any required param is missing/`None` (`macros/internal/metadata_processing/check_required_parameters.sql:15`).
### Example — basic call
```sql
{{ config(materialized='incremental', unique_key='HK_HUB_CUSTOMER') }}
{%- set src_pk = 'HK_HUB_CUSTOMER' -%}
{%- set src_nk = 'CUSTOMER_ID' -%}
{%- set src_ldts = 'LOAD_DATETIME' -%}
{%- set src_source = 'RECORD_SOURCE' -%}
{%- set source_model = 'stage_customer' -%}
{{ automate_dv.hub(src_pk=src_pk, src_nk=src_nk,
src_ldts=src_ldts, src_source=src_source,
source_model=source_model) }}
```
### Example — multi-source with `vault_insert_by_rank` and error avoidance
```sql
{{ config(materialized='vault_insert_by_rank',
rank_column='RANK',
rank_source_models=['stage_a', 'stage_b']) }}
{%- set src_pk = 'HK_HUB_ACCOUNT' -%}
{%- set src_nk = 'ACCOUNT_NUMBER' -%}
{%- set src_ldts = 'LOAD_DATETIME' -%}
{%- set src_source = 'RECORD_SOURCE' -%}
{%- set src_extra_columns = ['RANK'] -%}
-- source_model as a list unions multiple staging models
{%- set source_model = ['stage_a', 'stage_b'] -%}
{{ automate_dv.hub(src_pk=src_pk, src_nk=src_nk,
src_extra_columns=src_extra_columns,
src_ldts=src_ldts, src_source=src_source,
source_model=source_model) }}
```
### Notes
When `model.config.materialized == 'vault_insert_by_rank'` the macro appends `config_meta_get('rank_column')` to the selected columns (`hub.sql:32`).
```
--------------------------------
### Basic call to xts macro
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/03-tables-other.md
Example configuration and invocation of the `xts` macro. It sets up an incremental model with a unique key, defines satellite metadata, and calls `automate_dv.xts` with the required parameters.
```sql
{{ config(materialized='incremental', unique_key='HK_HUB_CUSTOMER') }}
{%- set src_pk = 'HK_HUB_CUSTOMER' -%}
{%- set src_ldts = 'LOAD_DATETIME' -%}
{%- set src_source = 'RECORD_SOURCE' -%}
{%- set src_satellite = {
'sat_name': {'sat': 'SATELLITE_NAME'},
'hashdiff': {'hashdiff': 'HASHDIFF'}
} -%}
{%- set source_model = ['sat_customer', 'sat_customer_profile'] -%}
{{ automate_dv.xts(src_pk=src_pk, src_satellite=src_satellite,
src_ldts=src_ldts, src_source=src_source,
source_model=source_model) }}
```
--------------------------------
### rank_columns usage example
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/04-staging.md
Example usage of the rank_columns macro. It defines a ranked_columns mapping and calls the macro to render a RANK() window expression.
```sql
{%- set ranked_columns = {
'RANK': {'partition_by': 'CUSTOMER_ID', 'order_by': 'LOAD_DATETIME', 'dense_rank': true}
} -%}
{{ automate_dv.rank_columns(columns=ranked_columns) }}
```
--------------------------------
### Example: automate_dv.null_columns with required and optional columns
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/04-staging.md
Example usage of the null_columns macro with a columns mapping. The macro renders NULL-handling expressions for required and optional columns, aliasing each as
_ORIGINAL and replacing NULLs with sentinel values from null_key_required (-1) and null_key_optional (-2).
```sql
{%- set null_columns = {
'required': ['CUSTOMER_ID', 'CUSTOMER_NAME'],
'optional': ['CUSTOMER_EMAIL']
} -%}
{{ automate_dv.null_columns(columns=null_columns) }}
```
--------------------------------
### null_columns and null_column_sql macros
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/04-staging.md
Documentation for the null_columns and null_column_sql macros, including signatures, parameters, return types, and examples.
```APIDOC
## `null_columns`
### Description
Renders NULL-handling expressions for `required` and `optional` columns: each column is aliased `_ORIGINAL` and replaced by a sentinel value when NULL. Sentinel defaults come from vars `null_key_required` (`-1`) and `null_key_optional` (`-2`). The default SQL uses `IFNULL`; `sqlserver__null_column_sql` uses `ISNULL`; `postgres__null_column_sql` uses `COALESCE`.
### Method
Macro (Jinja)
### Signature
```jinja
{%- macro null_columns(source_relation=none, columns=none) -%}
```
### Parameters
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `source_relation` | Relation | no | `none` | Accepted for signature compatibility; not used by the default body |
| `columns` | mapping | no | `none` | `{'required': , 'optional': }` |
### Return Type
Renders ` AS _ORIGINAL, IFNULL(, '') AS ` rows.
### Example
```sql
{%- set null_columns = {
'required': ['CUSTOMER_ID', 'CUSTOMER_NAME'],
'optional': ['CUSTOMER_EMAIL']
} -%}
{{ automate_dv.null_columns(columns=null_columns) }}
```
---
## `null_column_sql`
### Description
Renders a single row pair for a column: ` AS _ORIGINAL, IFNULL(, '') AS ` (or dialect-specific equivalent). Dispatches to `default__null_column_sql`, `sqlserver__null_column_sql`, or `postgres__null_column_sql` based on the active adapter.
### Method
Macro (Jinja)
### Signature
```jinja
{%- macro null_column_sql(col_name, default_value) -%}
```
### Parameters
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `col_name` | string | yes | — | Column name |
| `default_value` | string | yes | — | Sentinel literal |
### Return Type
Renders a single row pair.
### Example
```sql
{{ automate_dv.null_column_sql('CUSTOMER_ID', '-1') }}
```
```
--------------------------------
### as_constant usage example
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/08-metadata-processing.md
Example usage of the as_constant macro. A leading '!' in the input causes the rest to be treated as a string literal and returned single-quoted; otherwise the string is returned as-is.
```jinja
{{ automate_dv.as_constant("'!CSV_CUSTOMER'") }} -- renders: 'CSV_CUSTOMER'
{{ automate_dv.as_constant('SYSDATETIME()') }} -- renders: SYSDATETIME()
```
--------------------------------
### Configure vault_insert_by_rank materialization
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/05-materialisations.md
Example configuration for the vault_insert_by_rank materialization. Requires rank_column and rank_source_models in the config. The model uses automate_dv.hub to create a hub from stage_customer.
```sql
{{ config(materialized='vault_insert_by_rank',
rank_column='RANK',
rank_source_models=['stage_customer']) }}
{%- set src_pk = 'HK_HUB_CUSTOMER' -%}
{%- set src_nk = 'CUSTOMER_ID' -%}
{%- set src_ldts = 'LOAD_DATETIME' -%}
{%- set src_source = 'RECORD_SOURCE' -%}
{%- set source_model = 'stage_customer' -%}
{{ automate_dv.hub(src_pk=src_pk, src_nk=src_nk,
src_ldts=src_ldts, src_source=src_source,
source_model=source_model) }}
```
--------------------------------
### AutomateDV hub macro usage example
Source: https://github.com/datavault-uk/automate-dv/blob/master/README.md
Shows the three-step usage pattern for AutomateDV: configure the model with config(), provide metadata via set statements, then call the hub macro. The ellipses (...) indicate placeholders for actual values.
```jinja
# Configure model
{{- config(...) -}}
# Provide metadata
{%- set src_pk = ... -%}
...
# Call the macro
{{ automate_dv.hub(src_pk, src_nk, src_ldts,
src_source, source_model) }}
```
--------------------------------
### User Data JSON
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/08-metadata-processing.md
An example JSON object showing user data with id, name, and email fields.
```json
{
"id": 1,
"name": "John Doe",
"email": "john@example.com"
}
```
--------------------------------
### Basic call to automate_dv.sat
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/02-tables-satellites.md
A minimal example of calling the `sat` macro with required parameters. It configures an incremental model with a unique key and sets the source model to 'stage_customer'.
```sql
{{ config(materialized='incremental', unique_key='HK_HUB_CUSTOMER') }}
{%- set src_pk = 'HK_HUB_CUSTOMER' -%}
{%- set src_hashdiff = 'HASHDIFF' -%}
{%- set src_payload = ['CUSTOMER_NAME', 'CUSTOMER_DOB'] -%}
{%- set src_ldts = 'LOAD_DATETIME' -%}
{%- set src_source = 'RECORD_SOURCE' -%}
{%- set source_model = 'stage_customer' -%}
{{ automate_dv.sat(src_pk=src_pk, src_hashdiff=src_hashdiff,
src_payload=src_payload,
src_ldts=src_ldts, src_source=src_source,
source_model=source_model) }}
```
--------------------------------
### t_link example usage
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/01-tables-hub-link.md
Example usage of the t_link macro in a dbt model. It configures the model as incremental with a unique key, sets the source columns, and calls the macro with the specified parameters.
```sql
{{ config(materialized='incremental', unique_key='HK_NH_LINK_ACCOUNT') }}
{%- set src_pk = 'HK_NH_LINK_ACCOUNT' -%}
{%- set src_fk = 'ACCOUNT_FK' -%}
{%- set src_ldts = 'LOAD_DATETIME' -%}
{%- set src_source = 'RECORD_SOURCE' -%}
{%- set source_model = 'stage_account' -%}
{{ automate_dv.t_link(src_pk=src_pk, src_fk=src_fk,
src_ldts=src_ldts, src_source=src_source,
source_model=source_model) }}
```
--------------------------------
### Example: Using type_string() and type_binary() macros
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/06-hash-prefix-casting.md
Shows usage of the type_string() and type_binary() macros. type_string() returns 'VARCHAR' on Snowflake and 'STRING' on BigQuery. type_binary() returns 'BINARY(16)' for MD5 on Snowflake.
```jinja
{{ automate_dv.type_string() }} -- 'VARCHAR' on Snowflake, 'STRING' on BigQuery
{{ automate_dv.type_binary() }} -- 'BINARY(16)' for MD5 on Snowflake
```
--------------------------------
### hash_columns usage example
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/04-staging.md
Example usage of the hash_columns macro. The hashed_columns mapping uses either a plain list (PK hash) or a mapping with columns and is_hashdiff. If a mapping lacks is_hashdiff, a warning is emitted and columns are hashed without hashdiff behaviour.
```sql
{%- set hashed_columns = {
'HK_HUB_LINK': {'columns': ['HK_CUSTOMER', 'HK_ACCOUNT'], 'is_hashdiff': false},
'HASHDIFF': {'columns': ['EFFECTIVE_FROM', 'CUSTOMER_NAME'], 'is_hashdiff': true}
} -%}
{{ automate_dv.hash_columns(columns=hashed_columns) }}
```
--------------------------------
### Call to automate_dv.sat with ghost record and source filtering
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/02-tables-satellites.md
Example of calling `sat` with `apply_source_filter=true` in the config. When `var('enable_ghost_records', false)` is true, a ghost record is inserted if its HASHDIFF is not already present.
```sql
{{ config(materialized='incremental', unique_key='HK_HUB_CUSTOMER',
apply_source_filter=true) }}
{%- set src_pk = 'HK_HUB_CUSTOMER' -%}
{%- set src_hashdiff = 'HASHDIFF' -%}
{%- set src_payload = ['CUSTOMER_NAME'] -%}
{%- set src_ldts = 'LOAD_DATETIME' -%}
{%- set src_source = 'RECORD_SOURCE' -%}
{%- set source_model = 'stage_customer' -%}
{{ automate_dv.sat(src_pk=src_pk, src_hashdiff=src_hashdiff,
src_payload=src_payload,
src_ldts=src_ldts, src_source=src_source,
source_model=source_model) }}
```
--------------------------------
### Composing ghost expressions manually
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/07-ghost-records.md
Example showing how to manually compose ghost expressions using the automate_dv.binary_ghost, automate_dv.date_ghost, and automate_dv.null_ghost macros. Useful when you need to build custom ghost record logic.
```sql
{{ automate_dv.binary_ghost('HK_HUB_CUSTOMER', 'md5') }},
{{ automate_dv.date_ghost('timestamp_ntz', 'LOAD_DATETIME') }},
{{ automate_dv.null_ghost('varchar', 'CUSTOMER_NAME') }}
```
--------------------------------
### nh_link
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/03-tables-other.md
Documentation for the nh_link macro, including signatures, parameters, return type, and usage examples.
```APIDOC
## nh_link
### Description
Loads the current state of a link together with payload columns; deduplicates source by PK + FK, then incremental anti-joins against `this`.
### Signature (dispatcher)
```jinja
{%- macro nh_link(src_pk, src_fk, src_payload, src_extra_columns, src_eff, src_ldts, src_source, source_model) -%}
```
### Signature (default implementation)
```jinja
{%- macro default__nh_link(src_pk, src_fk, src_payload, src_extra_columns, src_eff, src_ldts, src_source, source_model) -%}
```
### Parameters
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `src_pk` | string / list | yes | — | Hash key |
| `src_fk` | string / list | yes | — | FK columns hashed into the key |
| `src_payload` | string / list / mapping | no | — | Payload columns |
| `src_extra_columns` | string / list | no | — | Extra columns |
| `src_eff` | string | no | — | Effective-from column |
| `src_ldts` | string | yes | — | Load timestamp |
| `src_source` | string | yes | — | Record source |
| `source_model` | string / mapping | yes | — | Source model |
### Return Type
`WITH stage AS (…), records_to_insert AS (SELECT DISTINCT … FROM stage LEFT JOIN this … WHERE this.pk IS NULL)` then `SELECT * FROM records_to_insert` (Databricks: `LEFT ANTI JOIN`).
### Throws
Compiler error from `check_required_parameters` (`nh_link.sql:8-10` — note `src_eff` is also required by the dispatcher even though it is optional in the default body).
### Example — basic call
```sql
{{ config(materialized='incremental', unique_key='HK_NH_LINK_ACCOUNT') }}
{%- set src_pk = 'HK_NH_LINK_ACCOUNT' -%}
{%- set src_fk = 'ACCOUNT_FK' -%}
{%- set src_payload = ['ACCOUNT_BALANCE', 'ACCOUNT_STATUS'] -%}
{%- set src_ldts = 'LOAD_DATETIME' -%}
{%- set src_source = 'RECORD_SOURCE' -%}
{%- set source_model = 'stage_account' -%}
{{ automate_dv.nh_link(src_pk=src_pk, src_fk=src_fk,
src_payload=src_payload,
src_ldts=src_ldts, src_source=src_source,
source_model=source_model) }}
```
### Example — `vault_insert_by_rank` variant
```sql
{{ config(materialized='vault_insert_by_rank', rank_column='RANK') }}
{%- set src_pk = 'HK_NH_LINK_ACCOUNT' -%}
{%- set src_fk = 'ACCOUNT_FK' -%}
{%- set src_payload = ['ACCOUNT_BALANCE'] -%}
{%- set src_ldts = 'LOAD_DATETIME' -%}
{%- set src_source = 'RECORD_SOURCE' -%}
{%- set source_model = 'stage_account' -%}
{{ automate_dv.nh_link(src_pk=src_pk, src_fk=src_fk,
src_payload=src_payload,
src_ldts=src_ldts, src_source=src_source,
source_model=source_model) }}
```
```
--------------------------------
### Example usage of select_hash_alg with 'sha'
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/06-hash-prefix-casting.md
Shows how to call select_hash_alg with the 'sha' hash type inside a dbt macro. The macro returns the SQL for the selected algorithm, which is used within the hash() function.
```sql
-- All three variants are used via var('hash') inside hash():
{{ automate_dv.select_hash_alg('sha') }}
```
--------------------------------
### Configure dbt vars in dbt_project.yml
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/configuration.md
Example of setting optional dbt variables in the consuming project's dbt_project.yml file. All variables are optional and defaults are platform-independent unless noted.
```yaml
# dbt_project.yml
vars:
hash: md5
enable_ghost_records: true
```
--------------------------------
### source_columns usage example
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/04-staging.md
Example usage of the source_columns macro. It retrieves the column names from the 'landing_customer' relation and assigns them to the 'cols' variable.
```sql
{%- set cols = automate_dv.source_columns(source_relation=ref('landing_customer')) -%}
-- cols == ['CUSTOMER_ID', 'CUSTOMER_NAME', ...]
```
--------------------------------
### nh_link vault_insert_by_rank variant
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/03-tables-other.md
Example of calling automate_dv.nh_link with vault_insert_by_rank materialization and a rank column. Uses a reduced payload compared to the basic example.
```sql
{{ config(materialized='vault_insert_by_rank', rank_column='RANK') }}
{%- set src_pk = 'HK_NH_LINK_ACCOUNT' -%}
{%- set src_fk = 'ACCOUNT_FK' -%}
{%- set src_payload = ['ACCOUNT_BALANCE'] -%}
{%- set src_ldts = 'LOAD_DATETIME' -%}
{%- set src_source = 'RECORD_SOURCE' -%}
{%- set source_model = 'stage_account' -%}
{{ automate_dv.nh_link(src_pk=src_pk, src_fk=src_fk,
src_payload=src_payload,
src_ldts=src_ldts, src_source=src_source,
source_model=source_model) }}
```
--------------------------------
### Basic link call: automate_dv.link with single source
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/01-tables-hub-link.md
Minimal dbt model configuration for building a link table from a single staging model. Uses source_model='stage_customer_account' and sets src_fk list. Renders a CTE chain that deduplicates on src_pk and filters fk_cols IS NOT NULL because stage_count == 1.
```sql
{{ config(materialized='incremental', unique_key='HK_LINK_CUSTOMER_ACCOUNT') }}
{%- set src_pk = 'HK_LINK_CUSTOMER_ACCOUNT' -%}
{%- set src_fk = ['HK_CUSTOMER', 'HK_ACCOUNT'] -%}
{%- set src_ldts = 'LOAD_DATETIME' -%}
{%- set src_source = 'RECORD_SOURCE' -%}
{%- set source_model = 'stage_customer_account' -%}
{{ automate_dv.link(src_pk=src_pk, src_fk=src_fk,
src_ldts=src_ldts, src_source=src_source,
source_model=source_model) }}
```
--------------------------------
### derive_columns usage example
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/04-staging.md
Example usage of the derive_columns macro. Values can be strings, lists (concatenated with ||), or mappings with source_column and escape. Supports as_constant !-prefix constants.
```sql
{%- set derived_columns = {
'LOAD_DATETIME': 'SYSDATETIME()',
'RECORD_SOURCE': "'CSV_CUSTOMER'",
'CUSTOMER_HASH': ['CUSTOMER_ID', "'|'", 'CUSTOMER_NAME'],
'CUSTOMER_NAME': {'source_column': 'CUSTOMER_NAME', 'escape': true}
} -%}
{{ automate_dv.derive_columns(source_relation=ref('landing_customer'),
columns=derived_columns) }}
```
--------------------------------
### Example: process_payload_column_excludes with exclude_columns
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/08-metadata-processing.md
Example usage of process_payload_column_excludes with a mapping payload containing exclude_columns. The macro resolves the payload to all source columns minus metadata-declared columns minus the excluded columns. Non-mapping payloads are returned unchanged.
```jinja
{%- set src_payload = {'exclude_columns': ['LOAD_DATETIME', 'RECORD_SOURCE']} -%}
{{ automate_dv.process_payload_column_excludes(src_pk, src_hashdiff, src_payload,
none, none, none, src_ldts, src_source,
source_model) }}
```
--------------------------------
### stage
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/04-staging.md
Documentation for the `stage` macro, the primary entry point for building staging SELECTs in the automate-dv dbt package.
```APIDOC
## `stage`
### Description
Builds a complete staging SELECT. Sources can be referenced by dbt model name (`ref` style) or source/table mapping (`sources` style). `include_source_columns` controls whether untouched source columns are emitted alongside derived/hashed/null/ranked columns. The macro composes a chain of CTEs: `source_data → derived_columns → null_columns → hashed_columns → ranked_columns → columns_to_select`.
### Signature (dispatcher)
```jinja
{%- macro stage(include_source_columns=none, source_model=none, hashed_columns=none, derived_columns=none, null_columns=none, ranked_columns=none) -%}
```
### Signature (default implementation)
```jinja
{%- macro default__stage(include_source_columns, source_model, hashed_columns, derived_columns, null_columns, ranked_columns) -%}
```
### Parameters
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `include_source_columns` | boolean | no | `true` | When false, only derived/hashed/null/ranked columns are emitted |
| `source_model` | string / mapping | yes | — | Model name (`ref` style) or `{source_name: table_name}` mapping |
| `hashed_columns` | mapping | no | — | `{alias: [cols]}` or `{alias: {'columns': [cols], 'is_hashdiff': true}}` |
| `derived_columns` | mapping | no | — | `{alias: ` string or list, or `{alias: {'source_column': …, 'escape': true/false}}` |
| `null_columns` | mapping | no | — | `{'required': [cols], 'optional': [cols]}` — see `null_columns` below |
| `ranked_columns` | mapping | no | — | `{alias: {'partition_by': …, 'order_by': …, 'dense_rank': bool}}` |
### Return Type
A `WITH … SELECT * FROM columns_to_select` statement. The source column list is obtained by `source_columns()` on the resolved relation; derived/null/hash/rank column names are excluded appropriately via `process_columns_to_select`.
### Errors
Throws a compiler error when `source_model is none` and `execute` (`stage.sql:24-38`):
```
Staging error: Missing source_model configuration. A source model name must be provided.
```
### Example — basic call
```sql
{%- set source_model = 'landing_customer' -%}
{%- set hashed_columns = {
'HK_HUB_CUSTOMER': {'columns': ['CUSTOMER_ID'], 'is_hashdiff': false},
'HASHDIFF': {'columns': ['CUSTOMER_NAME', 'CUSTOMER_DOB'], 'is_hashdiff': true}
} -%}
{%- set derived_columns = {
'LOAD_DATETIME': 'SYSDATETIME()',
'RECORD_SOURCE': "'CSV_CUSTOMER'"
} -%}
{%- set null_columns = {'required': ['CUSTOMER_EMAIL']} -%}
{{ automate_dv.stage(include_source_columns=true,
source_model=source_model,
hashed_columns=hashed_columns,
derived_columns=derived_columns,
null_columns=null_columns) }}
```
### Example — sources-style source_model and error handling
```sql
{%- set source_model = {'raw_source': 'customer_table'} -%}
{%- set hashed_columns = {
'HK_HUB_CUSTOMER': 'CUSTOMER_ID'
} -%}
-- Raises a compiler error if source_model is omitted:
{{ automate_dv.stage(include_source_columns=false,
source_model=source_model,
hashed_columns=hashed_columns) }}
```
```
--------------------------------
### Using is_list and is_something in a Jinja conditional
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/09-internal-helpers.md
Example usage of the is_list and is_something predicates in a Jinja conditional. Both return booleans.
```jinja
{% if automate_dv.is_list(source_model) %}...{% endif %}
{% if automate_dv.is_something(derived_columns) %}...{% endif %}
```
--------------------------------
### Macro signatures for fusion_compat.sql
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/09-internal-helpers.md
Exact macro signatures from the source file `macros/supporting/fusion_compat.sql`. These are the three macros provided by the dbt Fusion compatibility shim: `_config_meta_lookup`, `config_meta_get`, and `config_meta_require`.
```jinja
{% macro _config_meta_lookup(key) %}
{% macro config_meta_get(key, default=none) %}
{% macro config_meta_require(key) %}
```
--------------------------------
### Usage example comparing END_DATE to max datetime sentinel
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/06-hash-prefix-casting.md
Shows how to compose cast_date and cast_datetime to compare an END_DATE column against the max datetime sentinel, with as_string=true.
```jinja
-- Compare an END_DATE column to the max datetime sentinel:
{{ automate_dv.cast_date(automate_dv.cast_datetime(automate_dv.max_datetime(), as_string=true)) }}
```
--------------------------------
### Logging helper macro signatures (wrap_message, log_warning, log_error, log_relation_sources)
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/09-internal-helpers.md
Exact macro signatures from the logging helpers. wrap_message boxes a message between === TYPE === borders; log_warning and log_error call exceptions.warn and exceptions.raise_compiler_error respectively (only when execute and not dbt compile); log_relation_sources calls dbt_utils.log_info('Loading .. from source(s)') (Databricks omits the database).
```jinja
{% macro wrap_message(message, type='WARNING') %}
```
```jinja
{%- macro log_warning(message) -%}
```
```jinja
{%- macro log_error(message) -%}
```
```jinja
{% macro log_relation_sources(relation, source_count) %}
```
--------------------------------
### Basic stage macro call with ref-style source_model
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/04-staging.md
Basic call to the `stage` macro using a dbt model name (`ref` style) as `source_model`. It defines hashed columns (including a hashdiff), derived columns, and null columns, then invokes `automate_dv.stage` with `include_source_columns=true`.
```sql
{%- set source_model = 'landing_customer' -%}
{%- set hashed_columns = {
'HK_HUB_CUSTOMER': {'columns': ['CUSTOMER_ID'], 'is_hashdiff': false},
'HASHDIFF': {'columns': ['CUSTOMER_NAME', 'CUSTOMER_DOB'], 'is_hashdiff': true}
} -%}
{%- set derived_columns = {
'LOAD_DATETIME': 'SYSDATETIME()',
'RECORD_SOURCE': "'CSV_CUSTOMER'"
} -%}
{%- set null_columns = {'required': ['CUSTOMER_EMAIL']} -%}
{{ automate_dv.stage(include_source_columns=true,
source_model=source_model,
hashed_columns=hashed_columns,
derived_columns=derived_columns,
null_columns=null_columns) }}
```
--------------------------------
### Default implementation signature for automate_dv.link
Source: https://github.com/datavault-uk/automate-dv/blob/master/_autodocs/api-reference/01-tables-hub-link.md
Exact signature for the `default__link` macro, the default platform implementation that contains the core logic (deduplication, ranking, FK filtering). Invoked by the dispatcher as `automate_dv.link`. Usually not called directly.
```jinja
{%- macro default__link(src_pk, src_fk, src_extra_columns, src_ldts, src_source, source_model) -%}
```