Data validation configuration reference

This page documents the validation workflow YAML and shared Worker TOML settings for AIM DMV data validation. For platform-specific prerequisites, connectivity, and data type mappings, see the per-platform pages linked from Data validation.

For SnowConvert AI CLI commands that generate and submit validation workflows, see Manual Migration with SnowConvert AI CLI: Data validation.

Validation workflow file overview

Validation is driven by a single YAML workflow file. Key sections:

SectionPurpose
source_platform / target_platformSource dialect and target (defaults to Snowflake)
validation_configurationGlobal L1/L2/L3 toggles, thresholds, early stopping, accepted transformations
comparison_configurationNumeric tolerance and optional type mapping file
acceptedTransformationsGlobal rules for expected source-to-target value pairs (optional)
database_mappings / schema_mappingsSource-to-target name maps
tablesTables to validate, with optional per-table overrides
viewsSame shape as tables, for view validation
objectsSame shape as tables, with optional objectType; omitting the type triggers runtime detection

Top-level object

PropertyTypeRequiredDescription
source_platformStringYesSource dialect: sqlserver, redshift, teradata, oracle, or postgresql.
target_platformStringDefaults to Snowflake.
target_databaseStringDefault target database for tables that don’t specify one.
validation_configurationObjectGlobal validation levels and options.
comparison_configurationObjectNumeric tolerance and optional type mapping file.
acceptedTransformationsArrayGlobal accepted-transformation rules. Merged with per-table rules.
database_mappingsObjectMap of source database names to Snowflake database names.
schema_mappingsObjectMap of source schema names to Snowflake schema names.
tablesArraySee noteTable entries to validate (each tagged object_type = "TABLE").
viewsArraySee noteView entries using the same shape as tables (each tagged object_type = "VIEW").
objectsArraySee noteEntries using the same shape as tables, plus an optional objectType (TABLE or VIEW). Omitting objectType resolves the type at runtime against the target Snowflake catalog. See Objects with runtime type detection.
target_partition_size_rowsIntegerDesired rows per partition. Mutually exclusive with target_partition_size_mb.
target_partition_size_mbIntegerDesired MB per partition. Default is 200 MB when both are omitted.
use_snowpipe_for_resultsBooleanWhen true (default), L2/L3 results are ingested via Snowpipe.
queryModifiersQueryModifiersOptional SQL hints for source queries. Default is unset (no hints). See Anti-locking and query modifiers.
validationCustomNormalizationsObjectWorkflow-wide overrides for L2/L3 normalization SQL templates. See Customizing normalization and metrics.
validationCustomMetricsObjectWorkflow-wide overrides for L2 metric definitions. See Customizing normalization and metrics.
validationCustomTypesObjectWorkflow-wide overrides for L1 source data type name mapping. See Customizing normalization and metrics.

tables, views, and objects are each individually optional, but the workflow must define at least one entry across the three.

Objects with runtime type detection

The top-level objects array is an alternative to tables and views that lets you list objects without committing to a type. Each entry uses the same shape as a tables or views entry, plus an optional objectType:

  • When objectType is TABLE or VIEW, the entry behaves exactly like the corresponding tables or views entry.
  • When objectType is omitted, AIM DMV resolves the type at runtime against the target Snowflake catalog. Only TABLE and VIEW are supported. If a detected type is something else (for example a materialized view) or the object doesn’t exist on the target, only that object’s check fails; other objects continue.

tables, views, and objects can be combined freely in the same workflow.

Validation configuration

When validation_configuration is omitted, defaults are: schema validation and metrics validation enabled; row validation disabled; when L3 is enabled, validation fingerprints each partition with MD5 row hashes and drills into individual cells on mismatches; max_failed_rows_number defaults to 1000; early_stopping_for_cell_by_cell_comparison defaults to true; early_stopping_for_row_hashing defaults to false.

PropertyTypeDescription
schema_validationBooleanLevel 1: schema and column consistency checks.
metrics_validationBooleanLevel 2: statistical metrics comparison.
row_validationBooleanLevel 3: row fingerprinting and cell drill-down on mismatches.
continue_on_failureBooleanWhether to continue to the next validation level after a failure.
max_failed_rows_numberIntegerCap on failed rows reported for L3 per partition and early-stop threshold (default 1000).
exclude_metricsBooleanWhen true, skips overflow-prone L2 aggregates: avg, sum, and stddev (default false).
apply_metric_column_modifierBooleanWhen true (default), applies a platform overflow guard to aggregate metrics such as sum and avg.
early_stopping_for_row_hashingBooleanWhen true, stops remaining row-hash partitions once max_failed_rows_number mismatches are ingested (default false).
early_stopping_for_cell_by_cell_comparisonBooleanWhen true, stops remaining cell drill-down partitions once max_failed_rows_number mismatches are ingested (default true).
early_stop_check_interval_minutesIntegerPoll interval when either early-stop flag is enabled (default 5).
early_stop_check_interval_secondsIntegerAlternative poll interval in seconds. Mutually exclusive with early_stop_check_interval_minutes.
acceptedTransformationsArrayRules merged with workflow-root and per-table rules.

Validation levels and result codes

Schema validation (L1) compares table name, column names, ordinal position, data types, character length, numeric precision and scale, nullability, and row count. Results use SUCCESS, WARNING (treated as a pass), or FAILURE.

Metrics validation (L2) compares row count, min, max, sum, average, null count, distinct count, standard deviation, and variance (metrics vary by column type). Numeric comparisons honor comparisonConfiguration.tolerance (default 0.001). Results use SUCCESS, WARNING, or FAILURE.

Row validation (L3) fingerprints each partition with MD5 row hashes, then drills into individual cells on mismatches. Row-level RESULT values include:

ResultMeaning
MISMATCHThe row matches on the index columns on both sides, but one or more compared values differ.
POSSIBLE_MISMATCHA provisional MISMATCH recorded while the table has accepted transformations configured. Reconciled before the workflow completes: rows matching an accepted rule are cleared, and the rest become MISMATCH.
NOT_FOUND_TARGETThe row exists on the source but has no matching row on the target (missing from the target).
NOT_FOUND_SOURCEThe row exists on the target but has no matching row on the source (extra row on the target).
DUPLICATE_SOURCEThe index-column key appears more than once on the source side.
DUPLICATE_TARGETThe index-column key appears more than once on the target side.
DUPLICATE_BOTH_SIDESThe index-column key is duplicated on both the source and the target.

Task-level failures are recorded in DATA_VALIDATION_ERROR, distinct from row-level MISMATCH results.

Comparison configuration

PropertyTypeDescription
toleranceNumberRelative tolerance for L2 metric comparisons (default 0.001, or 0.1%).
type_mapping_file_pathStringOptional path to a custom type mapping file.

Accepted transformations

Accepted transformations whitelist specific source-to-target value pairs so AIM DMV does not report them as L3 mismatches. See Accepted transformations for the end-to-end flow and POSSIBLE_MISMATCH lifecycle.

Rules can appear at three levels (unioned per table):

  1. Workflow root (acceptedTransformations)
  2. Global validation_configuration.acceptedTransformations
  3. Per-table acceptedTransformations or nested validation_configuration.acceptedTransformations

Each rule object:

PropertyTypeRequiredDescription
columnStringOne of column or columnPatternExact source column name (case-insensitive).
columnPatternStringOne of column or columnPatternRegex tested against the source column name.
sourceValueString or nullYesExpected source value. Use null to represent SQL NULL.
targetValueString or nullYesExpected target value after migration.

Example:

validation_configuration:
  row_validation: true
acceptedTransformations:
  - column: status
    sourceValue: "ACTIVE"
    targetValue: "1"
  - columnPattern: "^flag_"
    sourceValue: null
    targetValue: "false"
tables:
  - fully_qualified_name: MYDB.MYSCHEMA.MYTABLE
    acceptedTransformations:
      - column: code
        sourceValue: "Y"
        targetValue: "YES"

Per-table and per-view entry

PropertyTypeRequiredDescription
fully_qualified_nameStringYesSource object name (format depends on platform).
use_column_selection_as_exclude_listBooleanDefault false.
column_selection_listString[]Columns to include or exclude (literals and/or Python regex).
target_nameStringTarget object name override.
target_databaseStringPer-table target database override.
target_schemaStringPer-table target schema override.
where_clauseStringFilter on the source side.
target_where_clauseStringFilter on the target side.
index_column_listString[]Columns used to align rows on the source (required for L3).
target_index_column_listString[]Columns used to align rows on the target.
column_mappingsObjectMap of source column name to target column name.
is_case_sensitiveBooleanCase sensitivity for identifiers and column filtering (default false).
object_typeStringTABLE (default) or VIEW. Set to VIEW to validate a view from a flat tables list instead of the views array.
column_names_to_partition_byString[]Columns for range-based partitioning during L2/L3.
target_partition_size_rowsIntegerPer-table rows per partition override.
target_partition_size_mbIntegerPer-table MB per partition override.
max_failed_rows_numberIntegerOverrides the global L3 cap for this object.
acceptedTransformationsArrayPer-table accepted-transformation rules.
validation_configurationObjectNested overrides for this object only.
queryModifiersQueryModifiersOptional SQL hints for source queries on this object. Default is unset (no hints). See Anti-locking and query modifiers.
excludeMetricsBooleanPer-table override for exclude_metrics.
applyMetricColumnModifierBooleanPer-table override for apply_metric_column_modifier.

Column filtering with regex patterns

Each entry in column_selection_list is matched against every column name:

  • Literal — plain string (for example LOAD_DATE), case-insensitive unless is_case_sensitive: true
  • Regex — entry wrapped in single quotes with r"..." inside (for example 'r".*_TS"')
use_column_selection_as_exclude_listBehavior
false (default)Include mode — only matched columns are validated
trueExclude mode — all columns except matched ones are validated

Partitioning

When column_names_to_partition_by is set, the Orchestrator splits the table into range-based partitions:

  1. Compute target rows-per-partition from target_partition_size_rows or target_partition_size_mb (default 200 MB).
  2. Apply internal caps for safe infrastructure bounds.
  3. Derive partition count as ceil(row_count / effective_rows_per_partition).

Anti-locking and query modifiers

User-configured anti-locking hints are off by default. Unless you set queryModifiers, AIM DMV runs plain source queries. Modifiers apply to source queries only, never the Snowflake target. L3 row-hash validation uses the same source modifiers, so dirty reads can cause false MISMATCH results.

Set queryModifiers at the workflow root or on individual table or view entries. See the QueryModifiers model in the Data migration configuration reference.

Per-platform behavior

PlatformDefault behaviorHow to customize
TeradataLOCKING ROW FOR ACCESS added automatically on every source scanNot configurable
SQL ServerNo automatic hintSet objectModifier: " WITH (NOLOCK)" at workflow root or per table
OracleAutomatic PARALLEL optimizer hint on large tablesOverride with selectModifier, or set selectModifier: "NONE" to disable
Amazon RedshiftNo automatic hintOpt-in pass-through via queryModifiers
PostgreSQLNo automatic hintOpt-in pass-through via queryModifiers

Pros and cons

ProsSource reads no longer block on or wait for locks held by production writers, so validation isn’t stalled by long-running source transactions. On Oracle, the parallel hint can speed large-table scans.
ConsWITH (NOLOCK) (and equivalent read-uncommitted hints) allow dirty reads: scans can see uncommitted rows that later roll back, which can produce false MISMATCH results during validation. Many DBAs disallow NOLOCK. Custom modifier strings are passed through verbatim, so an invalid hint can cause source query errors.
RecommendationLeave hints off unless source locking is actually blocking your workflow. When you do enable them, prefer running validation against a quiesced or low-write window.

Workflow example

queryModifiers:
  objectModifier: " WITH (NOLOCK)"
tables:
  - fully_qualified_name: MYDB.dbo.ORDERS
    queryModifiers:
      objectModifier: " WITH (NOLOCK)"

Worker TOML example

[connections.source.sqlserver.query_modifiers]
object_modifier = " WITH (NOLOCK)"
select_modifier = ""

Warning

WITH (NOLOCK) uses read-uncommitted semantics. During validation, dirty reads can produce false MISMATCH results that do not reflect the committed source data.

Customizing normalization and metrics

AIM DMV ships built-in normalization and metric templates per platform and data type. The workflow keys below override those defaults at the workflow root only (not per table). Each key splits overrides into source and target arrays by platform side. Set these in the validation workflow file, not in Worker TOML.

Custom normalization (validationCustomNormalizations)

Normalization is the SQL AIM DMV wraps around each column so source and target values compare in a canonical form (consistent date, number, or string formatting) for L2 metrics and L3 hashing.

PropertyTypeDescription
sourceArrayOverrides applied on the source platform side.
targetArrayOverrides applied on the Snowflake target side.

Each array entry is a single-key map of data type → SQL template. Keys are data types (uppercased), not column names. Use the "{{ col_name }}" placeholder for the column reference.

An override for a data type replaces the built-in template for that type; other types are unchanged.

Use custom normalization when benign formatting differences would otherwise show as L3 mismatches (for example float precision or Teradata PERIOD types).

Example:

validationCustomNormalizations:
  source:
    - BIGINT: "TRIM(TO_CHAR(\"{{ col_name }}\", '999990.000000000000000000'))"
    - DECIMAL: "TRIM(TO_CHAR(\"{{ col_name }}\", '999990.000000000000000000'))"
  target:
    - NUMBER: "TO_CHAR(\"{{ col_name }}\", 'FM999990.000000000000000000')"

Custom metrics (validationCustomMetrics)

L2 metrics are chosen by column data type. A DEFAULT set applies to types without a specific entry.

PropertyTypeDescription
sourceArrayMetric overrides on the source platform side.
targetArrayMetric overrides on the Snowflake target side.

Each array entry:

FieldTypeDescription
datatypeStringSource or target data type (uppercased).
metricsArrayMetric definitions for that type.
replace_allBooleanWhen true, removes all built-in metrics for the type before applying the listed metrics (default false).

Each metric definition:

FieldTypeDescription
nameStringMetric name (for example count, sum, min, max, stddev).
metric_queryStringSQL aggregate using "{{ col_name }}". A null or empty value removes that metric from the built-in set.
metric_return_datatypeStringData type used to normalize the metric result.
metric_column_modifierStringOptional overflow guard override for this metric.

Control which metrics run with these related settings:

SettingDefaultPurpose
metrics_validationtrueEnable or disable L2 entirely (global or per table).
exclude_metrics / excludeMetricsfalseSkip overflow-prone aggregates: avg, sum, stddev.
apply_metric_column_modifier / applyMetricColumnModifiertrueApply platform overflow guards to aggregate metrics.
comparisonConfiguration.tolerance0.001Relative threshold for numeric L2 metric comparison only.

Example:

validationCustomMetrics:
  source:
    - datatype: BIT
      replace_all: false
      metrics:
        - name: sum
          metric_query: "SUM(\"{{ col_name }}\")"
          metric_return_datatype: NUMBER
        - name: stddev_pop
          metric_query: "STDDEV_POP(\"{{ col_name }}\")"
          metric_return_datatype: FLOAT
  target: []

L1 type mapping overrides (validationCustomTypes)

validationCustomTypes overrides how source data type names map for L1 schema comparison. This is distinct from normalization (L2/L3).

PropertyTypeDescription
sourceArrayList of single-key maps, each from an original source type name to the normalized type name.

Example:

validationCustomTypes:
  source:
    - "PERIOD(DATE)": "VARCHAR(40)"

Worker configuration

Workers reuse the same TOML format as Data Migration. See Data migration configuration reference for the full property list.

Workers that execute validation tasks must have the validation runtime available. The [connections.source.*] section matches the source platform documented on each Validating Data from … page.

Observability

Validation metadata lives under SNOWCONVERT_AI.DATA_VALIDATION by default. Filter queries by WORKFLOW_ID. See The SNOWCONVERT_AI database for tables, views, workflow management procedures, and sample queries.