Migrate from Great Expectations

Keep the checks you already wrote. Drop the runner, the suite repo, and the data docs tier. Translate Expectation Suites to ODCS YAML with a short Python recipe and import into AnomalyArmor.

What the recipe does

Walks your Expectation Suite, maps the common expectation types to ODCS validity and schema rules, and emits a single YAML document you can paste into /migrate/soda (the shared ODCS entry point). Expectations that do not translate are flagged in stderr so you can rewrite them as custom SQL rules or discard them.

  • expect_column_values_to_not_be_null → ODCS not_null
  • expect_column_values_to_be_between → ODCS range
  • expect_column_values_to_be_unique → ODCS unique
  • expect_column_values_to_be_in_set → ODCS in_set
  • expect_table_row_count_to_be_between → ODCS row_count

The recipe

Save as ge_to_odcs.py, run it from your GE project root, and pipe the output to a YAML file.

ge_to_odcs.py
# ge_to_odcs.py — convert Great Expectations Expectation Suites to ODCS YAML.
# Requires an existing GE context and PyYAML.
from great_expectations.data_context import FileDataContext
import yaml

ctx = FileDataContext(project_root_dir="./great_expectations")
suite = ctx.suites.get(name="my_suite")

validity = []
for e in suite.expectations:
    t = e.expectation_type
    kw = e.kwargs
    col = kw.get("column")
    if t == "expect_column_values_to_not_be_null":
        validity.append({"column": col, "rule": "not_null"})
    elif t == "expect_column_values_to_be_between":
        validity.append({
            "column": col,
            "rule": "range",
            "min": kw.get("min_value"),
            "max": kw.get("max_value"),
        })
    elif t == "expect_column_values_to_be_unique":
        validity.append({"column": col, "rule": "unique"})
    elif t == "expect_column_values_to_be_in_set":
        validity.append({"column": col, "rule": "in_set", "values": kw.get("value_set")})
    elif t == "expect_table_row_count_to_be_between":
        validity.append({
            "rule": "row_count",
            "min": kw.get("min_value"),
            "max": kw.get("max_value"),
        })
    else:
        # Fall through — flag for manual review.
        print(f"[warn] unmapped expectation: {t}")

odcs = {
    "apiVersion": "v3.1.0",
    "kind": "DataContract",
    "name": suite.name,
    "customProperties": {"anomalyarmor": {"validity": validity}},
}
print(yaml.safe_dump(odcs, sort_keys=False))

Then run: python ge_to_odcs.py > contract.yaml and paste the resulting YAML into the migration form at /migrate/soda.

What does not translate automatically

Custom Python expectations, row-condition expectations with complex predicates, and multi-column aggregate expectations. The recipe prints a warning for each one. Rewrite as custom SQL rules in ODCS, or drop them if they are no longer needed.

Ready to move the checks over?

Great Expectations migration

Frequently Asked Questions

Not yet. The translation from Expectation Suites JSON to ODCS YAML is a short Python recipe, published on this page. Most teams copy the recipe, run it locally against their GE context, and paste the resulting YAML into /migrate/soda (which is the shared ODCS entry point). A native importer is on the roadmap.