demoprep / tests /test_validator_schema_consistency.py
mikeboone's picture
guard: catch CREATE/INSERT column mismatches before and during Snowflake load
2cc63cd
Raw
History Blame Contribute Delete
4.65 kB
"""Guard against CREATE TABLE / INSERT column mismatches — catch them in-memory,
at validate_bundle() time, instead of ~10 minutes later as a cryptic Snowflake
'invalid identifier' error deep inside an executemany (see the Gap e2e failure:
FACT_CAMPAIGN_PERFORMANCE's row loader referenced a CHECKOUT_INITIATED column
CREATE TABLE never declared).
"""
from __future__ import annotations
from demoprep_app.dataset.contracts import DatasetBundle, DatasetColumn, DatasetTable
from demoprep_app.dataset.validator import ValidationReport, _check_schema_consistency
from demoprep_app.scenario.contract import ScenarioContract
def _scenario() -> ScenarioContract:
return ScenarioContract(
company_name="Acme",
company_url="https://example.com",
use_case="Marketing Funnel",
scenario_type="campaign_performance",
fact_grain="campaign-day",
)
def test_schema_consistency_passes_for_a_clean_bundle():
bundle = DatasetBundle(
scenario=_scenario(),
tables=[
DatasetTable(
name="FACT_CAMPAIGN_PERFORMANCE",
grain="campaign-day",
columns=[
DatasetColumn("FACT_CAMPAIGN_PERFORMANCE_KEY", "fact_key", "NUMBER", nullable=False),
DatasetColumn("IMPRESSIONS", "impressions", "NUMBER", nullable=False),
DatasetColumn("CLICKS", "clicks", "NUMBER", nullable=False),
],
rows=[{"FACT_CAMPAIGN_PERFORMANCE_KEY": 1, "IMPRESSIONS": 100, "CLICKS": 5}],
is_fact=True,
)
],
)
report = ValidationReport()
_check_schema_consistency(bundle, report)
assert report.integrity_errors == []
def test_schema_consistency_catches_a_row_key_with_no_declared_column():
# Mirrors the Gap failure: the row loader would INSERT a column
# (CHECKOUT_INITIATED) that CREATE TABLE never declared for this table.
bundle = DatasetBundle(
scenario=_scenario(),
tables=[
DatasetTable(
name="FACT_CAMPAIGN_PERFORMANCE",
grain="campaign-day",
columns=[
DatasetColumn("FACT_CAMPAIGN_PERFORMANCE_KEY", "fact_key", "NUMBER", nullable=False),
DatasetColumn("ADD_TO_CART", "add_to_cart", "NUMBER", nullable=False),
DatasetColumn("CONVERSIONS", "conversions", "NUMBER", nullable=False),
],
rows=[
{
"FACT_CAMPAIGN_PERFORMANCE_KEY": 1,
"ADD_TO_CART": 10,
"CONVERSIONS": 2,
"CHECKOUT_INITIATED": 6, # not a declared column
}
],
is_fact=True,
)
],
)
report = ValidationReport()
_check_schema_consistency(bundle, report)
assert len(report.integrity_errors) == 1
assert "FACT_CAMPAIGN_PERFORMANCE" in report.integrity_errors[0]
assert "CHECKOUT_INITIATED" in report.integrity_errors[0]
def test_schema_consistency_catches_column_names_that_collide_after_normalization():
# Two distinct Python-level names that normalize to the same SQL identifier
# would make CREATE TABLE emit a duplicate column.
bundle = DatasetBundle(
scenario=_scenario(),
tables=[
DatasetTable(
name="FACT_CAMPAIGN_PERFORMANCE",
grain="campaign-day",
columns=[
DatasetColumn("Checkout Initiated", "checkout_initiated", "NUMBER", nullable=False),
DatasetColumn("Checkout-Initiated", "checkout_initiated_2", "NUMBER", nullable=False),
],
rows=[{"Checkout Initiated": 1, "Checkout-Initiated": 2}],
is_fact=True,
)
],
)
report = ValidationReport()
_check_schema_consistency(bundle, report)
assert len(report.integrity_errors) == 1
assert "CHECKOUT_INITIATED" in report.integrity_errors[0]
assert "duplicate column" in report.integrity_errors[0]
def test_schema_consistency_ignores_empty_tables():
bundle = DatasetBundle(
scenario=_scenario(),
tables=[
DatasetTable(
name="EMPTY_DIM",
grain="empty",
columns=[DatasetColumn("EMPTY_DIM_KEY", "dimension_key", "NUMBER", nullable=False)],
rows=[],
)
],
)
report = ValidationReport()
_check_schema_consistency(bundle, report)
assert report.integrity_errors == []