Changelog
Deprecation policy
GX Core follows Semantic Versioning 2.0.0, including its guidelines for deprecation.
When we deprecate public functionality, we will
- update our documentation to let you know about the change.
- issue a new minor release with the deprecation in place.
Before we completely remove the functionality in a new major release, there will be at least one minor release that contains the deprecation so that you can smoothly transition.
Deprecation timeline
This table lists every deprecated item, the version that deprecated it, and the version that removes it; a row is never deleted, even after the removal ships.
| Deprecated | Since | Removal | Replacement |
|---|---|---|---|
String values for numeric batch parameters (year, month, day, …) | 1.21.0 | 2.0.0 | Pass integers |
_atomic_prescriptive_template | 0.15.43 | 1.17.1 | |
str support for Validator.validate run_id | 0.13.0 | 1.17.0 | RunIdentifier or dict |
ColumnMetricProvider (and DeprecatedMetaMetricProvider) | 0.13.25 | 1.17.0 | ColumnAggregateMetricProvider |
Batch args data_context, datasource_name, batch_parameters, batch_kwargs | 0.14.0 | 1.17.0 | |
PandasDBFSDatasource | 1.16.0 | 2.0.0 | PandasFilesystemDatasource |
SparkDBFSDatasource | 1.16.0 | 2.0.0 | SparkFilesystemDatasource |
schema_name argument of TableAsset / add_table_asset | 1.14.0 | 2.0.0 | Schema-qualified table_name |
DatabaseStoreBackend, TupleStoreBackend family, QueryStore, MetricStore | 1.0.0 | 1.13.0 | |
String-style row_condition | 1.9.0 | 2.0.0 | RowCondition expression objects |
RuleBasedProfiler | 1.0.0 | 1.5.1 | |
DataContext.add_or_update_datasource | 1.3.0 | 2.0.0 | context.data_sources.add_* / update_* |
context.get_datasource | 1.1.2 | 2.0.0 | context.data_sources.get |
result_url on CheckpointResult | 1.1.2 | 1.1.2 | |
mostly on ExpectColumnUniqueValueCountToBeBetween | 1.1.0 | 1.1.0 | |
force_reuse_spark_context argument of SparkDFExecutionEngine / Spark datasources | 1.0.0 | 2.0.0 | spark_config |
get_or_create_spark_application() | 1.0.0 | 2.0.0 | Create the Spark session outside GX |
get_or_create_spark_session() | 1.0.0 | 2.0.0 | Create the Spark session outside GX |
MapMetricProvider.is_sqlalchemy_metric_selectable | 0.16.1 | 2.0.0 | |
context.sources.delete_<type> CRUD methods | 0.17.2 | 2.0.0 | context.sources.delete |
| V2 API style custom rendering | 0.13.28 | 2.0.0 | |
gx-redshift install extra (alias of redshift) | 1.21.0 | 2.0.0 | great_expectations[redshift] |
CloudDataContext and cloud mode of get_context(...) | 1.18.0 | 2.0.0 | gx.get_context(mode="file") or mode="ephemeral" |
1.24.0 (2026-10-07)
Compatibility: Python <3.14,>=3.10 → <3.15,>=3.10; numpy added (python_version >= "3.14"); pandas added (python_version >= "3.14"); pydantic added (python_version >= "3.14")
Highlights
-
Python 3.14 support — Great Expectations now installs and runs on Python 3.14, and the supported range is Python 3.10 through 3.14. On Python 3.14 installs resolve numpy 2.3.2 or later, pandas 2.3.3 or later, and pydantic 2.13.0 or later. The
clickhouseandteradataextras are not supported on 3.14, and Python 3.15 and later still requireGX_PYTHON_EXPERIMENTAL. (#12280)pip install great_expectations # now works on Python 3.14 -
New Expectation: ExpectColumnTypeToBe — A schema-level Expectation that checks a column's declared type, separate from the row-level
ExpectColumnValuesToBeOfType. It works on pandas, SQLAlchemy and Spark, returns onlyobserved_valuein its result, and reportssuccess=Falsewithobserved_value=Nonefor a missing column. Note that pandas 3 infers different default dtypes than pandas 2 for string and datetime columns, so re-checktype_when upgrading pandas. (#12186)import great_expectations.expectations as gxe
batch.validate(gxe.ExpectColumnTypeToBe(column="order_id", type_="int64")) -
Escape character for the LIKE pattern Expectations — The four LIKE pattern Expectations accept an optional single-character
escape, which emits anESCAPEclause so_and%can be matched literally and identically across backends. Omitting it produces exactly the SQL generated before. BigQuery and ClickHouse raise a clear error naming the dialect, because neither supports a usable ESCAPE clause; escape wildcards with a backslash inside the pattern there instead. Both renderers now disclose the escape character. (#12154)import great_expectations.expectations as gxe
gxe.ExpectColumnValuesToMatchLikePattern(column="c", like_pattern="a!_b", escape="!") -
Objects now resolve through the Data Context that owns them — With more than one Data Context in a process, expectation suites, validation definitions, checkpoints, batch definitions, the validator and a checkpoint's actions now read, write and run against the context they came from rather than whichever context happens to be current. Data Docs are built into the owning context's site,
${VARIABLE}references in Slack, Teams and Email settings resolve from the owning context's configuration, and a "not found" error for an object that belongs to no context now names the context the lookup consulted. An object that belongs to no context still resolves through the current one. (#12297, #12298, #12302, #12303)c1 = gx.get_context(mode="ephemeral")
suite = c1.suites.add(gx.ExpectationSuite(name="my_suite"))
c2 = gx.get_context(mode="ephemeral") # c2 is now current
suite.add_expectation(...) # still lands in c1 -
Database URLs are masked without being mangled —
PasswordMasker.mask_db_urlkeeps every part of a database URL except the secrets: query strings, fragments, IPv6 brackets and empty authorities survive, absent usernames and hosts are no longer printed asNone, and passwords containing/,?or#no longer raise. Credentials passed as query parameters (password=,odbc_connect=,private_key_file_pwd=) are now masked on both code paths, with an allowlist of safe-to-display parameter names, and any value that is not a<scheme>://...URL is masked whole. (#12242) -
Column names with spaces, hyphens, dots or keywords work in row conditions — On pandas and on Spark, a
row_conditionreferring to a column whose name is not a bare identifier is now escaped before it reaches the query engine, so names such as"Total Amount","a.b","x-y","from"and"Incident Number"filter the rows they name instead of raising a syntax error or silently validating the wrong rows. (#12238, #12285)gxe.ExpectColumnValuesToNotBeNull(
column="status",
row_condition=Column("Total Amount") > 15,
)
Changes
Features
- The four LIKE pattern Expectations accept an optional single-character
escapethat emits anESCAPEclause so_and%can be matched literally and portably; BigQuery and ClickHouse raise a clear error naming the dialect, and omittingescapeproduces exactly the SQL generated before. (#12154) - Added
ExpectColumnTypeToBe, a batch-level Expectation that checks a column's declared type on pandas, SQLAlchemy and Spark, reporting onlyobserved_valueand returningsuccess=Falsewithobserved_value=Nonefor a missing column. (#12186) - Added support for Python 3.14: the supported range is now 3.10 to 3.14 with dependency floors for numpy, pandas and pydantic on 3.14, and four comparison fixes also change behavior on 3.10 to 3.13 —
CaseInsensitiveStringno longer compares equal to arbitrary non-string objects,ExceptionInfoinequality defers to the other operand,ExpectationConfiguration.isEquivalentToreturnsFalsefor non-configurations, andExpectationValidationResultequality no longer raises when its expectation config is a plain dict. Theclickhouseandteradataextras are not supported on 3.14. (#12280)
Bug fixes
- On Spark, column names that are not bare SQL identifiers are quoted in generated filter strings, so a hyphenated name such as
id-nno longer silently validates the wrong rows and a spaced name such asIncident Numberno longer raises a parse error. (#12285) - A checkpoint's actions now run against the Data Context that owns the checkpoint: Data Docs are built into that context's site, Data Docs URLs are looked up there, and
${VARIABLE}references in Slack, Teams and Email settings resolve from its configuration. An action run directly, outside a checkpoint, still resolves through the current context. (#12303) - Validation definitions, checkpoints, batch definitions and the validator now run, save and check freshness against the Data Context that owns them, so with two contexts in one process an object no longer reports "has changed since it has last been saved", writes results to the wrong project, or validates another context's data source of the same name. (#12302)
- Masked database URLs keep their query string, fragment, IPv6 brackets and empty authority, no longer invent
Noneusernames or hosts, no longer raise on passwords containing/,?or#, and now mask credentials passed as query parameters on both masking paths; values that are not URLs are masked whole. (#12242) - An Expectation Suite obtained from a Data Context now reads and writes through that context, so
add_expectation,delete_expectationandsavechange the context the suite came from even while another is current, andsuites.add_or_updateof an existing name writes to the context whose factory was called. (#12298) - A "not found" error for an expectation suite, validation definition, checkpoint or batch definition that belongs to no Data Context now names the context the lookup consulted, and the batch definition miss message no longer nests a whole sentence inside the name. (#12297)
- SQLite engines that GX creates now close their pooled database connections once the engine is collected, so on Python 3.13 and later users no longer see
ResourceWarning: unclosed databasefrom a GX SQL datasource or execution engine going out of scope. (#12301) - A
row_conditionmay now contain single quotes, so conditions such ascol == 'value'are accepted instead of raising an invalid-configuration error; the newline restriction is unchanged. (#12258) ExpectColumnValuesToBeInSeton SQL backends ignoresNoneentries invalue_set, so values outside the set are flagged as unexpected instead of every row passing, matching pandas behavior; the unexpected-index query no longer renders a NULL literal. (#12277)ExpectColumnValuesToBeIncreasingandExpectColumnValuesToBeDecreasingon pandas now compare a datetime column's differences against a zero of the matching dtype, so a correctly ordered datetime column succeeds instead of reporting every row as unexpected. (#12270)column.standard_deviationandExpectColumnStdevToBeBetweennow work on a SQLite database added withadd_sql, returning the sample standard deviation instead of raisingno such function: stddev_samp;add_sqlitebehavior is unchanged. (#12212)- The
unexpected_index_queryproduced for Spark results is now a valid Python expression with the condition rendered as a quoted SQL string, so it parses and evaluates, including for in-set and regex conditions; where Spark cannot resolve the condition the quoted display string is used as a fallback. (#12220) - On pandas, a
row_conditionreferring to a column whose name is not a valid Python identifier — a space, dot or hyphen in the name, or a Python keyword — is now escaped with backticks, so the condition filters the intended rows instead of producing a syntax error reported as a failed validation. (#12238) - A query-metric or
UnexpectedRowsExpectationquery containing a literal brace — a JSON or array literal, a regex quantifier, or a LIKE pattern — now reports an error that quotes the query and explains that braces must be doubled, instead of a bareKeyErrororValueErrorfrom string formatting. (#12236)
Maintenance
- Bumped the docs site's proxy-addr dependency from 2.0.7 to 2.0.8. (#12296)
- Bumped the docs site's source-map-js dependency from 1.2.1 to 1.2.2. (#12295)
- Bumped the docs site's joi dependency from 17.13.7 to 17.13.8. (#12294)
- Bumped the docs site's compression dependency from 1.8.1 to 1.8.2. (#12293)
- Bumped the docs site's dompurify dependency from 3.4.13 to 3.4.16. (#12284)
- Bumped the docs site's fast-uri dependency from 3.1.7 to 3.1.8. (#12282)
- Bumped the docs site's brace-expansion dependency from 1.1.18 to 1.1.21. (#12281)
- Brought the
tests/datasourcesuite under the type checker by removing its mypy exclusions and fixing the reported type errors. (#12259) - Brought the Data Docs and Slack renderer modules under the type checker and fixed the defects it exposed: a content-block renderer now renders no content for a failed or unrenderable validation result instead of raising, the Data Docs index skips a result the context cannot find with its existing warning, and a Data Docs site configured with
cloud_modeorge_cloud_modenow raises the GX Cloud shutdown error. (#12256) - Added explicit
@overridedecorators to the expectation-core and renderer methods mypy's explicit-override check reported, with no behavioral change. (#12193) - CI now defines the supported Python versions once and derives every job's interpreter matrix from that single list, with no change to which interpreters run. (#12278)
- The CLA status check retries a transient failure from the contributor-handle endpoint up to five times before giving up, so a signed contributor's pull request no longer loses its CLA gate to an intermittent blip; the check still fails closed when every attempt fails. (#12275)
Contributors
Thanks to @DhanushPillay (first contribution), @feiiiiii5, @iamdpsingh (first contribution), @ptimizeroracle, @Rodrigo-Palma (first contribution), @kamalesh404 (first contribution), @umanggarg754 (first contribution), @Star-cloud626, @krisnaparahita (first contribution), @LucasLeao18 (first contribution).
1.23.2 (2026-09-25)
Compatibility: sqlalchemy now <2.1 (extras snowflake, databricks)
Highlights
-
Fixes GX on SQLAlchemy 2.1 — SQLAlchemy 2.1.0, released 2026-09-24, broke GX 1.23.1 and earlier on Python 3.11+, where every SQL extra resolves it by default. Depending on the backend,
import great_expectationsfailed whenever snowflake-sqlalchemy was installed, every Databricks query failed, driverlesspostgresql://URLs could not load a driver, BigQuery queries comparing against a float failed, SQL Server reported mixed-case and upper-case tables as missing, andexpect_column_values_to_be_of_type(type_="Numeric")failed on float columns. 1.23.2 fixes all of these: thesnowflakeanddatabricksextras stay below SQLAlchemy 2.1 until their dialects support it, and every other SQL extra runs on 2.1. Python 3.10 is unaffected, since SQLAlchemy 2.1 requires Python 3.11. If you can't upgrade yet, pinsqlalchemy<2.1; do the same if you install snowflake-sqlalchemy or databricks-sqlalchemy outside GX's extras. (#12269)pip install --upgrade 'great_expectations[snowflake]' # include your extras so the SQLAlchemy cap applies -
Regex Expectations work on ClickHouse — The four regex Expectations now run on ClickHouse, which does not support
regexp_like(). ClickHouse is covered by integration tests for these Expectations. (#12222)gx.expectations.ExpectColumnValuesToMatchRegex(column="name", regex="^A") -
Correct substring matching for regex Expectations on Snowflake — Snowflake's
REGEXPoperator anchors patterns to the whole value, so unanchored patterns behaved differently there than on other backends. Regex Expectations on Snowflake now use substring semantics that match every other GX backend, while preserving the user's pattern. (#12221)gx.expectations.ExpectColumnValuesToMatchRegex(column="name", regex="ell") -
Nested struct columns supported in Spark value-counts Expectations — On the Spark engine, Expectations that rely on the
column.value_countsmetric — includingExpectColumnMostCommonValueToBeInSetandExpectColumnKLDivergenceToBeLessThan— now work for dotted nested struct paths such asaddress.city, instead of returning an empty result with an unresolved-column error. (#12231)gx.expectations.ExpectColumnMostCommonValueToBeInSet(column="address.city", value_set=["Springfield"])
Changes
Bug fixes
- GX works on SQLAlchemy 2.1, which broke 1.23.1 on several backends: the
snowflakeanddatabricksextras are capped below 2.1, a broken snowflake-sqlalchemy install no longer preventsimport great_expectations, driverlesspostgresql://URLs fall back to psycopg2 when psycopg is unavailable, BigQuery rendersDoubleasFLOAT64, SQL Server reflects mixed-case tables, theNumerictype name matches float columns again, and database URL masking keeps the database and query string verbatim. (#12269) - Validation results containing an infinite
Decimalvalue — for example the maximum, mean or sum of a PostgreSQLnumericcolumn or a pandas column ofDecimalvalues — now serialize as float infinity instead of raisingdecimal.InvalidOperation. (#12254) - Regex Expectations on Snowflake now match substrings, consistent with other backends, rather than requiring the pattern to match the entire column value. (#12221)
UnexpectedRowsExpectationno longer misreads a query as containing a JOIN when the letters appear inside a string literal, a column name such asjoin_date, a quoted identifier or a comment; such queries are aliased correctly again and no longer fail with a syntax error on MySQL and SQL Server. (#12249)- Building validators on multiple threads no longer serializes or deadlocks on Python 3.10 and 3.11: concurrent validator construction now proceeds independently per instance while still building each validator only once. (#12232)
- Regex Expectations now work on ClickHouse, which lacks
regexp_like(); other SQL dialects are unchanged. (#12222) - Type Expectations on ClickHouse now compare and report the underlying SQL type for nullable columns instead of the
Nullable(T)wrapper, soExpectColumnValuesToBeOfTypeandExpectColumnValuesToBeInTypeListbehave as expected. (#12219) - The Spark
column.value_countsmetric now resolves nested struct columns such asaddress.city, so Expectations built on it return results instead of an unresolved-column error. (#12231)
Docs
- The changelog entries for releases 1.0.0 through 1.17.0 are rewritten in the structured format, and the previously missing 1.13.1 release now has its own entry. (#12227)
- The changelog entries for releases 1.17.1 through 1.23.0 are rewritten in the structured format, and the deprecation timeline gains rows for the
gx-redshiftextra alias and forCloudDataContext/ cloud mode ofget_context. (#12225)
Maintenance
- Redshift CI jobs are capped to three concurrent runs against the shared cluster, and test teardown now drops every test schema with retries so failed runs no longer leak schemas. No user-visible change. (#12257)
Contributors
Thanks to @adimalkar, @Rayan-and-beyond (first contribution), @nanjeshramesh, @feiiiiii5, @alibro005, @pentaoa (first contribution).
1.23.1 (2026-09-18)
Known issue: on Python 3.11+, this release resolves SQLAlchemy 2.1 (released 2026-09-24), which it does not support. Upgrade to 1.23.2, or pin sqlalchemy<2.1.
Highlights
-
Spark now evaluates each regex independently with match_on="all" — On Spark, ExpectColumnValuesToMatchRegexList with match_on="all" now checks every regex separately against each column value, so patterns anchored at different positions (such as ^A and [0-9]{3}$) both match a value that satisfies them. This matches the behavior already seen on Pandas and SQL. (#12198)
gxe.ExpectColumnValuesToMatchRegexList(
column="id",
regex_list=["^A", "[0-9]{3}$"],
match_on="all",
) -
Each Validator reports results for its own Batch when a datasource is reused — Validators built on the same datasource no longer borrow one another's Batch. Running two validation definitions on threads, or creating two validators from one datasource on a single thread, now evaluates and reports each validator's own data, with the correct batch_id, batch_spec and batch_definition on the result. This fixes a long-standing latent bug made reachable by #12148 in the 1.23.0 release. (#12211)
validator_a = context.get_validator(batch_request=request_a)
validator_b = context.get_validator(batch_request=request_b)
# validator_a still validates request_a's batch
result = validator_a.expect_table_row_count_to_equal(value=3) -
A Spark schema saved in great_expectations.yml reloads correctly — A persisted spark_schema is now read back through StructType.fromJson, so reopening a File Data Context round-trips the schema instead of failing inside PySpark. Values that are not an accepted schema form now raise a validation error naming the field and the accepted types. (#12200)
context = gx.get_context(mode="file")
asset = context.data_sources.get("spark_ds").get_asset("my_asset")
assert asset.spark_schema is not None -
GX config files are read and written as UTF-8 regardless of locale — config_variables.yml and great_expectations.yml, and the .gitignore read while scaffolding a project, are now opened with an explicit UTF-8 encoding. Projects containing non-ASCII values or comments can be created and reloaded on hosts with a non-UTF-8 locale, and a project YAML file that is not valid UTF-8 now raises an error naming the file instead of a bare decode error. (#12182, #12204)
-
A gallery-wide test tier for data sources — A new gallery support tier asserts a measured test result across the entire shipped expectation library — one case per registered expectation, each pairing a passing and a failing configuration — and nine data sources (pandas in-memory and filesystem CSV, SQLite, MySQL, PostgreSQL, Trino, BigQuery, Databricks and Redshift) now declare it after being measured against the full gallery. (#12150)
Changes
Features
- Adds a gallery support tier that asserts a passing test result over the whole shipped expectation library, with nine data sources declaring it, a required CI lane per member, membership and coverage guards, and a measurement mode for evaluating new candidate backends. (#12150)
Bug fixes
- ExpectColumnValuesToMatchRegexList with match_on="all" on Spark now evaluates each regex independently, so patterns anchored at different positions no longer fail on values that satisfy them all. (#12198)
- A Validator now keeps the identity of the Batches it loaded even when its execution engine is shared, so concurrent validations and multiple validators on one datasource each evaluate and report their own Batch; a configuration naming a batch the engine does not hold now raises instead of silently validating the most recently loaded batch. (#12211)
- The remaining config file reads and writes in the serializable data context are pinned to UTF-8, so scaffolding a project with a non-ASCII .gitignore and reading or updating great_expectations.yml work under a non-UTF-8 locale; an unreadable project YAML now raises an error naming the file. (#12204)
- A spark_schema persisted in great_expectations.yml is loaded back through StructType.fromJson so the schema round-trips when the context is reopened, and an unsupported value raises a validation error naming the field and the accepted types. (#12200)
- The Spark test-connection test, which covers behavior when PySpark is unavailable, is now skipped when PySpark is installed so it no longer fails for contributors with PySpark in their environment. (#12199)
- config_variables.yml is now read and written as UTF-8, so saving and reloading a configuration variable containing non-ASCII characters works on hosts with a non-UTF-8 locale. (#12182)
Docs
- The changelog now carries a deprecation timeline table listing every deprecated item, the version that deprecated it, and the version that removes it. (#12224)
- Documentation fixes: the credential-configuration pages now point at gx/uncommitted/config_variables.yml, a mistagged code fence highlights again, a misspelled snippet name is corrected, and doubled words and spelling errors across the core docs, ADRs, gallery docs and contrib READMEs are fixed. (#12177)
- Oracle is now documented on the connection-string reference (oracle+oracledb://...?service_name=...), the compatibility reference with its tested database version, and the data source method reference via add_sql. (#12167)
Maintenance
- The pull request title check now requires exactly one current tag at the start of the title, and the contributor docs and template name only the four current tags. (#12223)
- The published package metadata now includes project URLs linking to the source repository, documentation and homepage, so PyPI and dependency-tracking services can associate the package with its repository. (#12207)
- The metric repository retriever tests are now type-checked, with concrete annotations replacing Any and the module removed from the mypy exclude list. (#12184)
- The expectations test suite is now type-checked, including two guards that could never fail being corrected to actually test whether an optional dependency imported, and the directory-level mypy exclusion removed. (#12185)
- Five more test modules are removed from the type-check exclusion list. (#12178)
Contributors
Thanks to @lakshayxi (first contribution), @feiiiiii5 (first contribution), @ptimizeroracle (first contribution), @alibro005 (first contribution), @yigitcan-ozturk, @toyeshhm (first contribution), @nanjeshramesh, @p-mandale (first contribution).
1.23.0 (2026-09-10)
Compatibility: new extra oracle
Highlights
-
great_expectations[oracle]is a supported install — Oracle is now a published install path: installing theoracleextra brings in the Oracle driver and floors SQLAlchemy at 2.0, so theoracle+oracledbdialect the connection string needs is always available. The SQL dialect installation-commands table documents the new row. (#12091)pip install 'great_expectations[oracle]' -
Daily and monthly Batch Definitions work on Oracle query assets — Adding a daily or monthly Batch Definition to a query asset on Oracle previously failed with
ORA-00907: missing right parenthesis, reported misleadingly as the partition column not being verifiable as a date or datetime. A query asset's SQL is now wrapped whole, so the Batch Definition can be created. As a side effect, a query whose SQL ends in a trailing line comment no longer breaks Batch Definition creation on any backend. (#12162)asset = datasource.add_query_asset(name="orders", query="SELECT id, created_at FROM my_table")
asset.add_batch_definition_daily(name="daily", column="created_at") -
Consistent verdict for z-score checks on zero or undefined variance —
ExpectColumnValueZScoresToBeLessThanused to disagree by backend on a constant column: pandas flagged every row as an outlier, PostgreSQL and SQL Server surfaced a division-by-zero error, and SQLite and MySQL quietly succeeded. All engines now agree that a column with zero or undefined standard deviation succeeds with no unexpected values. Anyone who relied on this Expectation to catch a stuck or constant column should useExpectColumnStdevToBeBetweenwith a non-zeromin_valueinstead. (#12145)gxe.ExpectColumnValueZScoresToBeLessThan(column="constant", threshold=1.96, double_sided=True)
# success=True, unexpected_count=0 on every backend -
Mixed-case column names no longer break uniqueness checks on SQL backends —
ExpectColumnValuesToBeUniqueraisedKeyError: '<column>'on case-insensitive SQL dialects (Databricks, PostgreSQL, Snowflake, SQL Server, Trino) whenever the column name was not already lower case and the result format asked for rows or unexpected indices. It now evaluates normally, so users who pinned to 1.19.1 for this reason can unpin. (#12180)gxe.ExpectColumnValuesToBeUnique(column="CustomerID") # result_format="COMPLETE" -
SQL execution engines are reused instead of rebuilt on every validation — Every validation against a SQL datasource used to build a new execution engine, with its own SQLAlchemy engine and connection pool, leaking an idle pooled connection per validation and re-running dialect setup each time. The engine is now cached as intended and rebuilt only when the datasource's connection configuration changes; a validation that follows a schema change still reflects the table afresh. (#12148)
datasource.get_execution_engine() is datasource.get_execution_engine() # now True
Changes
Bug fixes
ExpectColumnStdevToBeBetweenon SQLite now reports an undefined standard deviation as anobserved_valueofNone— matching every other backend — instead of returning a result with noobserved_valueand an opaque "user-defined function raised exception" error, for columns with fewer than two non-null values and for empty tables. (#12168)ExpectColumnValuesToBeUniqueno longer raisesKeyErroron SQL backends when a column name is not lower case and the result format requests rows or unexpected indices. (#12180)ExpectColumnValueZScoresToBeLessThannow succeeds with no unexpected values on columns whose standard deviation is zero or undefined, on every backend, instead of failing on pandas or raising a division-by-zero error on PostgreSQL and SQL Server. (#12145)- Reading validation results and project YAML no longer fails with a
UnicodeDecodeErrorunder a non-UTF-8 system locale: filesystem store reads and project-configuration reads and writes are now pinned to UTF-8. (#12125) - Daily and monthly Batch Definitions can now be added to Oracle query assets, which previously failed with
ORA-00907: missing right parenthesis; a query asset whose SQL ends in a line comment also works on every backend now. (#12162) - A query asset whose SQL ends in a
--comment no longer fails validation: the raw SQL is normalized before it is wrapped, so appended text cannot land inside a trailing comment. (#12124) - SQL datasources now reuse their cached execution engine across calls instead of rebuilding it — and leaking a pooled connection — on every validation, while a validation following a schema change still reflects the table afresh. (#12148)
Docs
- Updated repository links in the development, docs-contribution, support and compatibility-reference pages to point at the
fivetran/great_expectationsrepository. (#12126)
Maintenance
pip install 'great_expectations[oracle]'is now a documented, supported install path, with SQLAlchemy floored at 2.0 so the Oracle dialect is available, and an install row added to the SQL dialect installation-commands table. (#12091)- Updated the docs site dependency joi from 17.13.4 to 17.13.7. (#12176)
- Updated the docs site dependency svgo from 3.3.4 to 3.3.5, picking up security hardening. (#12175)
- Removed five unreferenced checkpoint test fixtures and an entirely dead test
conftest.py. (#12174) - Brought the previously excluded modules under
tests/integration/into the type check, correcting their annotations and removing the covering exclude patterns. (#12173) - Brought the seven previously excluded modules under
tests/data_context/into the type check and removed their exclude patterns. (#12171) - Updated the docs site dependency colord from 2.9.3 to 2.10.0. (#12170)
- Brought the partition-and-sample execution engine test modules into the type check, fixing their annotations and removing the covering exclude pattern. (#12169)
- Removed the unreachable
match_onvalue key from the not-match-like-pattern-list metric, so the metric declares only the options it actually reads;ExpectColumnValuesToNotMatchLikePatternListnever acceptedmatch_onand still rejects it. (#12157) - Brought all modules under
tests/core/into the type check and removed their exclude patterns. (#12140) - Brought the modules under
tests/render/into the type check with annotation-only changes, leaving rendering behavior unchanged. (#12152) - Brought the validator metric-calculator and validation-graph test modules into the type check and removed their exclude patterns, with no production behavior change. (#12149)
- Updated the docs site dependency fast-uri from 3.1.5 to 3.1.7, picking up security fixes. (#12151)
- Updated the docs site dependency browserslist from 4.28.1 to 4.28.8. (#12155)
- Contributors opening pull requests from forks once again receive the welcome comment: the broken Slack notification steps and unreachable workflow conditions were removed, and the pyspark 4 and marshmallow 4 lanes now gate required CI and publishing. (#12159)
- Brought
tests/test_utils.py,tests/actions/andtests/checkpoint/test_checkpoint.pyinto the type check, including fixes so a failed database connection surfaces its original error instead of anAttributeErrorfrom the cleanup path. (#12146) - The integration test harness now maps fixture float and datetime columns to portable SQL types, so fixture values are stored as declared instead of being silently rounded or failing table creation on some backends, with new tests pinning the per-backend renderings. (#12147)
- Added a contract suite covering create, update and create-or-update for every registered fluent datasource type, and completed the type stubs so nineteen previously untyped factory methods now expose real signatures and return types to callers. (#12141)
- Generalized the test harness's data source declaration record so non-SQL data sources can declare support tiers, and derived the lists that gate CI from those declarations rather than maintaining them by hand. (#12110)
- Tightened the declared types for resolved metric values, render-content payloads and metric cache keys so callers type-checking against these APIs see fewer false diagnostics, with no runtime or signature changes. (#12116)
Contributors
Thanks to @siddharthgaur1 (first contribution), @Star-cloud626 (first contribution), @nanjeshramesh, @adimalkar (first contribution), @AnandkumarMall (first contribution), @Ryota-Di (first contribution), @yigitcan-ozturk (first contribution), @MannXo, @iamfeldman (first contribution).
1.22.0 (2026-08-31)
Compatibility: marshmallow minimum 3.7.1 → 3.18.0
Highlights
-
Marshmallow 4 is now supported — Great Expectations now installs and runs against both Marshmallow 3 and Marshmallow 4, so it can be installed alongside deployments that pin Marshmallow 4 (such as Apache Airflow 3.3). The supported range is now
marshmallow>=3.18.0with no upper bound; the declared 3.7.1 floor was unreachable in practice, so no currently-working environment is excluded. (#12092, #12118)pip install great_expectations marshmallow==4.3.1 -
Oracle is now a live-tested backend, with three Oracle defects fixed — Oracle joins the SQL test harness with live curated coverage, and the gaps that coverage exposed are fixed: regex Expectations now execute on Oracle instead of raising, query-based Expectations such as
UnexpectedRowsExpectationnow run because the derived-table alias is rendered in the form Oracle's grammar accepts, and daily and monthly batch definitions now work because the date-part string cast carries a length Oracle accepts. No other backend's rendered SQL changes. (#12085, #12103, #12104, #12102)batch_definition = asset.add_batch_definition_daily(
name="daily", column="event_date"
) -
add_storeno longer crashes and empties great_expectations.yml — Callingcontext.add_store()with an existing store's name and a config containing astore_backendkey crashed and leftgreat_expectations.ymlat 0 bytes, making the project unloadable. The config is now serialized before the file is opened, so a serialization failure leaves the existing file byte-for-byte intact, and the context id is written as a string that YAML can represent. (#12081)current = context.config.stores[context.expectations_store_name]
context.add_store(
name=context.expectations_store_name,
config={
"class_name": current["class_name"],
"store_backend": dict(current["store_backend"]),
},
) -
Clearer errors for unsupported regex dialects and masked Azure account keys — Regex Expectations run against a SQL dialect with no regex support now report
Regex is not supported for dialect <name>inexception_infoinstead of an empty message, and Azure connection strings are masked regardless of field order so an account key can no longer appear unmasked in aStoreConfigurationError. (#12109, #12094) -
Data Docs pages render for validation results with no run_id —
context.build_data_docs()silently dropped a validation result's page when the result'smetahad no"run_id"key. Such results now render, with run name and run time shown as__none__. (#12098)context.build_data_docs() # renders a page for every persisted result -
Documentation for the bundled agent skills — A new environment-setup page teaches how to install, verify, use, upgrade, and remove the agent skills that ship inside the
great_expectationspackage, including the overwrite contract and the three skills as one path. (#12074, #12106)python -m great_expectations skills install
python -m great_expectations skills list
Changes
Features
- Marshmallow 4.x is now supported alongside Marshmallow 3 on every supported Python version, with the supported range narrowed to
marshmallow>=3.18.0and the<4.0.0cap removed;config_versionbounds checking behaves identically on both majors. (#12092)
Bug fixes
context.add_store()no longer crashes and truncategreat_expectations.ymlto 0 bytes when re-supplying a store's own config containing astore_backendkey; the project config is now serialized before the file is opened, the context id is persisted as a string, and an absent context id stays empty rather than becoming the string "None". (#12081)- The BigQuery taxi test fixtures now drop their table by name during teardown instead of enumerating every schema on the server, removing the multi-minute stalls that cancelled the docs-snippets CI job. Test infrastructure only; no shipped code path changes. (#12119)
- Regex Expectations run against a SQL dialect without regex support (such as SQL Server) now report "Regex is not supported for dialect <name>" in
exception_infoinstead of an empty exception message, with the dialect name rendered cleanly. (#12109) ExpectColumnPairValuesToBeInSeton pandas now returns a verdict instead of aMetricResolutionErrorwhen the evaluated rows do not use a zero-based consecutive index, such as after null filtering or with a custom DataFrame index. (#12097)- Non-security md5 calls now pass
usedforsecurity=False, so batch identification, dataframe fingerprinting, and partitioning/sampling work on FIPS-enabled hosts. No computed digests change. (#12099) - Azure Blob Storage connection strings are now masked by parsing key=value pairs rather than matching one fixed field order, so a string with reordered fields or no
EndpointSuffixno longer raises aStoreConfigurationErrorcontaining the raw URL and account key. (#12094) context.build_data_docs()now renders a page for a validation result whosemetahas no"run_id"key (or whoserun_idisNone), defaulting run name and run time to__none__instead of silently dropping the page. (#12098)- MySQL, Microsoft SQL Server, and Redshift now declare a backend tier, so they run the metrics parameterizations they were silently absent from (+56, +44, and +56 tests respectively), and a new comparison keeps the two data-source list definitions from parting again; four regex metric modules exclude SQL Server, which has no regex operator. (#12107)
- Query-based Expectations such as
UnexpectedRowsExpectationnow execute on Oracle: the derived-table alias is rendered through one shared helper that omitsASonly for the grammar that rejects it, and the literal-boolean predicate rewrite now also applies to Oracle. No other backend's rendered SQL changes. (#12104) - Regex Expectations now execute on Oracle instead of raising
NotImplementedError, via a new Oracle branch in the dialect-regex helper that rendersREGEXP_LIKEin both positive and negated forms. No other dialect's rendered SQL changes. (#12103) add_batch_definition_dailyandadd_batch_definition_monthlynow work on Oracle: the multi-date-part partition query's string cast supplies an explicit length for the dialect that requires one, so batch retrieval no longer fails withORA-00906. Curated coverage for daily and monthly batch definitions was added for every curated backend. (#12102)
Docs
- Restructured the "Install agent skills" page for progressive disclosure — what the skills do now comes before prerequisites and install, a new "Use the skills" section follows install, maintenance detail is grouped under keeping the skills up to date, and the
--symlinkfailure wording matches the installer's actual behavior. (#12106) - Documentation that teaches batch parameters now passes integers for numeric batch parameters uniformly across file, SQL, and directory sources, and the prose saying the accepted type depends on the asset family has been removed. (#12066)
- Added a documentation page covering the agent skills bundled with GX: what they are, how to install and verify them with
python -m great_expectations skills installandskills list, the overwrite contract, the three skills as one path, and how to upgrade and remove them. (#12074)
Maintenance
- Added a CI lane that installs the Marshmallow 4.x line, asserts the resolution actually landed on 4.x, and runs the unit suite against it. (#12118)
- The SQL Server ODBC driver install script now bounds every apt call with a timeout, restricts its index refresh to the Microsoft repository, retries a failed install once, and the docs-snippets job gained a 30-minute timeout, so the step can no longer hang indefinitely. (#12079)
- The Azure Blob Storage docs fixtures run against live storage again, with the account URL and container read from environment variables instead of a retired hardcoded host; the Spark ABS fixtures remain off. (#12117)
- The docs-creds-needed CI leg now requests the BigQuery, SQL Server, and Redshift backends it already installs, so seven previously-skipped docs fixtures run; Snowflake and Azure stay unrequested and one Redshift fixture stays gated by name for lack of test data. (#12114)
- The five pandas S3 docs fixtures run again, with the bucket read from a repository variable and authentication moved from static access keys to a role assumed through GitHub's OIDC provider; the S3 Spark fixtures remain skipped. (#12111)
- Added a guard that compares the mypy configuration's relaxation surface against a committed inventory and fails the CI type-check in both directions, so adding an exclusion or relaxing override must be made visible in review. (#12115)
- Removed two structural blockers to type-checking the test tree: deleted an
__init__.pyunder a hyphenated, unimportable directory and gavetests/integration/test_script_runner.pyits own shell helper instead of importing one fromassets/. (#12113) - Cleaned up the mypy configuration so it reflects the codebase: 41 dead exclude patterns, 3 dead overrides, the SQLAlchemy import suppression and 1.x plugin, and 6 inert third-party suppressions removed; the generated version-file exclusion is anchored and the linter-ignore script's path filter corrected. (#12112)
- Oracle joins the SQL data-source test harness as a live-tested backend, with a thin-mode
oracledbdriver requirement for the test lane, a pinned Oracle 21c container, anoraclepytest marker and CI lane, and curated-tier coverage; nogreat_expectations[oracle]extra is published yet. (#12085)
Contributors
Thanks to @Dev-iL (first contribution), @ArjunPakhan (first contribution), @joebasrawi (first contribution), @nanjeshramesh, @dkling-it (first contribution), @hemalrajput18 (first contribution), @MannXo (first contribution).
1.21.0 (2026-08-19)
Compatibility: new extra gcs; gx-sqlalchemy-redshift removed (extra gx-redshift); sqlalchemy-redshift added (extra gx-redshift); sqlalchemy minimum → 1.4.0 (extra redshift)
Highlights
-
Integer batch parameters work on every datasource family — Numeric batch parameters such as
yearandmonthnow accept integers on file, directory, and SQL assets alike, so a singlebatch_parametersdict drives one checkpoint spanning files and a warehouse. Digit strings still work but now emit a deprecation warning. A SQL request that matches nothing also explains why, distinguishing an empty table or column from candidates that exist but did not match, and naming the offending parameter and value. (#12065)checkpoint.run(batch_parameters={"year": 2020, "month": 4}) -
Agent-skill guidance ships with the package — Great Expectations now bundles version-matched guidance for coding agents covering data source configuration, expectation authoring, and checkpoint orchestration, installable into a project's agent discovery directories. The guidance names the right optional dependency group for a missing driver, offers a batching cadence instead of assuming one, carries reuse-safe worked examples, and will not install packages, edit configuration files, create a project directory, or save files unless the user asked for it. (#12061, #12062, #12063, #12068, #12073)
python -m great_expectations skills install --target all
python -m great_expectations skills list -
Two experimental expectations promoted into the core library —
ExpectColumnValuesToNotBeOutliers(IQR and standard-deviation methods) and the multicolumn values-equal expectation are now supported core expectations on Pandas, SQL, and Spark, with null-safe evaluation, Gallery metadata, prescriptive rendering, and public exports. (#12011, #12018)gx.expectations.ExpectColumnValuesToNotBeOutliers(
column="fare_amount", method="iqr", multiplier=1.5
) -
Redshift installs the upstream SQLAlchemy dialect —
pip install 'great_expectations[redshift]'now resolves the upstreamsqlalchemy-redshift1.0.0 dialect with SQLAlchemy 2, replacing the Great Expectations fork and lifting asqlalchemy<2.0.0pin that had been holding the dialect back at a three-year-old release. Thegx-redshiftextra keeps working as a deprecated alias that resolves identically. (#12044)pip install 'great_expectations[redshift]' -
S3 requests are attributable to Great Expectations — S3 clients built by Great Expectations now send a
great-expectations/<version>user-agent suffix, appended to any user-supplied agent string rather than replacing it, so operators and S3-compatible providers can see which requests originate from Great Expectations. The S3 Data Source docs also clarify thatendpoint_urlis how you connect to a non-AWS S3-compatible store. (#11937) -
Data Docs no longer advertises a removed suite-editing workflow — The "How to Edit This Suite" button and its popup, which pointed at a CLI command and notebook workflow that no longer exist, are gone from expectation suite and validation results pages, and expectation suite, profiling, and site index pages no longer render an empty "Actions" card. Validation results pages keep the Actions card and its Show All / Failed Only filter. (#12078)
Deprecations
- Digit strings for numeric batch parameters (for example
\{"year": "2024", "month": "02"}) are deprecated; pass integers instead (\{"year": 2024, "month": 2}). Removal in 2.0.0. (#12065) - The
gx-redshiftinstall extra is deprecated and is now an alias that resolves identically toredshift; usegreat_expectations[redshift]. Removal in 2.0.0. (#12044)
Changes
Features
- S3 clients now carry a
great-expectations/<version>user-agent suffix, appended to any user-supplied agent string, and the S3 Data Source docs clarify thatendpoint_urlconnects to an S3-compatible object store. (#11937) ExpectColumnValuesToNotBeOutliersis now a supported core expectation on Pandas, SQL, and Spark, with IQR and standard-deviation detection, consistent null handling, inclusive threshold boundaries, and a clear error for unsupported methods. (#12011)- The bundled agent skills now state up front, and again at each point they could act, that they will not install dependencies, edit configuration files, or save unrequested files without the user asking; the data source skill's batch-parameter examples were also corrected to use integers. (#12073)
- The multicolumn values-equal expectation is promoted into the core library with null-safe equality on Pandas, SQLAlchemy, and Spark, plus Gallery metadata, prescriptive rendering, and public exports. (#12018)
- A third bundled agent skill covers checkpoint orchestration — binding assets and suites into validation definitions, grouping them into a named checkpoint with post-run actions, and verifying with one run — and the expectations skill now routes onward into it; writing a session out to a project also persists validation definitions and checkpoints and reports when an object already existed. (#12068)
- Numeric batch parameters accept integers on file, directory, and SQL assets, so one
batch_parametersdict drives a checkpoint spanning files and SQL; digit strings still work but warn, and a SQL request matching nothing now explains whether the data is absent or the parameter did not match. (#12065) - The bundled agent skills will not create a project directory unless the user has agreed to it and named the path, and the write-out offer is now the end of the flow rather than something done in the same breath as reporting results. (#12063)
- The data source skill now names the correct optional dependency group for a missing driver (read from the installed distribution), keeps the batching question open until the verification probe reports the available columns, and carries the reuse guard inside its worked examples so copying one cannot silently replace an existing data source. (#12062)
- Great Expectations ships agent-skill guidance for configuring data sources and expectations, installable with
python -m great_expectations skills installand listable withskills list; the installer leaves already-correct destinations alone, refuses directories it did not write, and requires--forceto replace user-edited copies. (#12061) - ClickHouse is onboarded as a first-class backend in the SQL integration test harness, which along the way fixed a quantile-metric helper that called a nonexistent execution-engine method and two shared test-harness defects. (#12053)
- Trino is onboarded onto the SQL backend integration-test harness with a pinned container, a declared backend record, corrected double-quote identifier quoting for the dialect, and full curated-tier coverage. (#12050)
- The SQL integration test harness gains a declarative backend framework: a new SQL backend is onboarded by declaring one frozen backend record (schema support, column type overrides, transaction mode, insert parameter limits, table schema items, tiers, and CI wiring) instead of adding dialect-specific branches, with onboarding documentation and a wiring drift check. (#12049)
Bug fixes
- The Python 3.12 minimum-version test job installs dependencies and runs tests again, restoring minimum-version coverage and unblocking the required CI gate. (#12076)
Maintenance
- The "How to Edit This Suite" button and its popup no longer appear in Data Docs, and expectation suite, profiling, and site index pages no longer render an empty "Actions" card; validation results pages keep the Actions card and its validation filter, and the
show_how_to_buttonssite config option still loads but gates nothing. (#12078) - The shipped
SparkDBFSDatasourceJSON schema description now includes the deprecation notice the Python API has carried since 1.16.0, so schema-driven consumers see it too. (#12077) - The distribution now ships version-matched expectation and datasource schema catalogs with index files mapping each datasource schema to its
add_or_update_*factory method and each expectation to its schema, description, data quality issues, and supported data sources. (#12055) - BigQuery test tables are created in the configured dataset rather than in a per-config dataset, and the cleanup job sweeps stale tables within that dataset instead of querying project-level metadata it lacks permission to read. (#12024)
- Added PostgreSQL integration coverage documenting that a quoted schema name on an asset is not honored as quoting today, with the passing bare-name control beside it so the behavior cannot be corrected without the test being updated. (#12051)
- Removed the
gx-redshiftCI launch key now that the Redshift lane selects the canonicalredshiftmarker; the deprecatedgx-redshiftinstall extra is unaffected. (#12060) - The
redshiftextra now installs upstreamsqlalchemy-redshift1.0.0 withsqlalchemy>=1.4.0instead of the Great Expectations fork, fixing a pin that had been silently installing a three-year-old dialect;gx-redshiftremains as a deprecated alias resolving identically. (#12044) - The pull request template and AGENTS.md now state the RFC threshold for new backend support, a new advisory check asks contributors to answer that question when a change looks like new backend support, and the superseded Markdown issue templates that bypassed triage labeling are removed. (#12043)
- The GCS documentation snippets run in CI again behind a dedicated
--gcsflag, and the Spark-on-GCS guide is migrated to the current asset API so it no longer documents a call that raises. (#12059) - Restored GCP credentials for the docs snippets CI job and made the credentials path absolute so it resolves after the snippet runner changes directories. (#12057)
- Corrected the stale patch paths in the pandas and Spark GCS datasource tests and added a
gcs_depsmarker and requirements file so they actually run in CI. (#12058) - GCS test and docs fixtures read the bucket name from a
GX_GCS_TEST_BUCKETenvironment variable and raise clearly when it is unset; the published GCS guides now show amy_bucketplaceholder instead of the real CI bucket. (#12056) - The SingleStore development container image used by CI is pinned to 0.2.82 instead of tracking
:latest. (#12054) - Bumped mermaid from 11.15.0 to 11.16.1 in the documentation site dependencies. (#12047)
- Bumped nanoid from 3.3.16 to 3.3.18 in the documentation site dependencies. (#12052)
- Bumped dompurify from 3.4.12 to 3.4.13 in the documentation site dependencies. (#12048)
Contributors
Thanks to @goanpeca (first contribution), @chavalasantosh (first contribution), @AtomicGlance (first contribution).
1.20.0 (2026-08-07)
Highlights
-
Quantile expectations are correct on SQLite and no longer error on all-null columns —
ExpectColumnQuantileValuesToBeBetweennow selects the right rank on SQLite and ignores null values when computing quantiles, so observed quantiles match the other backends. A column with no non-null values now reports an unmet expectation —success: falsewith null observed values and per-quantile success details — on every backend instead of raising aTypeErroron SQL backends or anIndexErroron Spark. (#12008, #12026)import great_expectations.expectations as gxe
suite.add_expectation(
gxe.ExpectColumnQuantileValuesToBeBetween(
column="passenger_count",
quantile_ranges={"quantiles": [0.25, 0.5], "value_ranges": [[1, 2], [1, 3]]},
)
) -
Faster
expect_column_values_to_be_uniqueon wide SQL tables — The SQLAlchemy implementation ofcolumn_values.uniquenow scans the source table once through a narrow window over only the target column, and only retrieves full rows (via a narrow duplicate-key join) whenSUMMARYorCOMPLETEresult formats are requested. Wide column-store tables — where the previous query was cancelled by Redshift's workload-management timeouts — now validate reliably. (#11863)import great_expectations.expectations as gxe
gxe.ExpectColumnValuesToBeUnique(column="id") -
Validating multiple expectations on the same metric no longer fails on strict SQL backends — When several expectations in a suite depend on the same underlying metric, the generated SQL now gives each metric a unique alias, so backends such as Postgres no longer reject the query with
Duplicated field name in view schema. (#11905) -
File-backed Data Contexts work on read-only, version-controlled projects —
gx.get_context(mode="file")now recognizes a project as already set up based on a committedgreat_expectations.ymlalone, instead of requiring the gitignoreduncommitted/runtime directories. A clean checkout on a read-only filesystem is no longer mistaken for an unscaffolded project and no longer crashes during initialization. (#12000)import great_expectations as gx
context = gx.get_context(mode="file", project_root_dir="/path/to/checkout") -
ExpectColumnValuesToMatchStrftimeFormatis now a supported core Expectation — The Expectation now carries full support metadata and a generated schema, appears in the Expectation Gallery with a properly rendered docstring and examples, and declares a backend matrix of Pandas and Spark (SQL is out of scope). (#12009)import great_expectations.expectations as gxe
gxe.ExpectColumnValuesToMatchStrftimeFormat(
column="event_date",
strftime_format="%Y-%m-%d",
mostly=0.95,
) -
Adding a table asset is much faster on projects with many schemas —
TableAsset.test_connection()now probes the table first and only lists server schemas if that probe fails, purely to refine the error message. On backends where schema listing is a server-wide metadata operation — for example a BigQuery project with thousands of datasets — adding a table asset no longer pays that cost. Table configurations whose schema name did not match the normalized schema listing but were otherwise accessible now succeed. (#12020)asset = datasource.add_table_asset(name="my_asset", table_name="my_table", schema_name="my_schema")
Changes
Features
ExpectColumnValuesToMatchStrftimeFormatis promoted to a supported core Expectation, with a corrected and Gallery-formatted docstring, support metadata, a generated JSON schema, a declared Pandas and Spark backend matrix, and expanded test coverage includingmostlythresholds. (#12009)
Bug fixes
ExpectColumnQuantileValuesToBeBetweenno longer reports a quantile one rank too low on SQLite and no longer raises on columns containing null values; quantile ranks are computed from non-null counts with exact fractional arithmetic, and the MySQL query applies the same null filter. (#12008)ExpectColumnQuantileValuesToBeBetweennow reports an unmet expectation, with null observed values and per-quantile success details, for a column that has no non-null values, instead of raising on SQL backends and Spark; the Spark metric returns one null per requested quantile socolumn.quantile_valueshas the same shape on every backend. (#12026)- Validating multiple expectations that share an underlying metric against a SQL backend no longer fails with a duplicated-field-name view schema error, because each bundled metric is now given a unique SQL alias. (#11905)
expect_column_values_to_be_uniqueon SQLAlchemy backends now runs a single narrow pass over the target column, and only joins back to the source for full-row details underSUMMARY/COMPLETEresult formats, eliminating the Redshift workload-management timeouts seen on very wide tables. (#11863)- A file-backed Data Context can now be created against a fully-scaffolded, version-controlled project on a read-only filesystem: an already-set-up project is recognized from its committed
great_expectations.ymlrather than from gitignoreduncommitted/directories, so a clean checkout is no longer destructively re-scaffolded. (#12000)
Maintenance
- BigQuery tests run in CI again — the temporary unconditional skip for BigQuery-marked tests was removed — and the external-warehouse CI jobs now fail after 30 minutes instead of hanging for hours. (#12016)
- Testing the connection for a table asset now probes the table first and only lists schemas on the failure path to refine the error message, so the operation no longer pays a server-wide metadata scan; error messages are unchanged. (#12020)
- Updated the documentation site's
fast-uridependency from 3.1.4 to 3.1.5, which includes a security fix. (#12019) - Ephemeral schemas created by the SQL integration test suite are now namespaced under a
gx_ci_test_prefix, and the stale-schema cleanup patterns were corrected to match hex suffixes so stale schemas are actually swept. No library behavior changes. (#12015) - Updated the documentation site's
brace-expansiondependency from 1.1.16 to 1.1.18. (#12014) - Updated the documentation site's
postcssdependency from 8.5.12 to 8.5.25. (#12013) - Commenting
/assign-meon an issue that is not yet labeled ready for work now gets a posted explanation of why the claim was declined and where to find issues open for claiming, instead of silently doing nothing. (#11999)
Contributors
Thanks to @SreeramaYeshwanthGowd (first contribution), @TemidayoA (first contribution), @leodrivera, @nanjeshramesh (first contribution).
1.19.1 (2026-07-24)
Highlights
-
Data Docs no longer errors when unexpected indices contain only id/pk columns — Validation results that report unexpected indices made up solely of the configured id/pk columns — including Spark and SQL runs and any run with unexpected values excluded — now render a count and index table in Data Docs instead of failing the result page with "No group keys passed!". (#11935)
-
Contributor License Agreement checks are now run by the project itself — The verification/cla-signed check is posted by the repository's own workflows rather than a third-party hosted app: it is reported on pull request heads and on merge-queue commits, fails closed when contributor status cannot be confirmed, leaves a single guiding comment naming any unsigned or unidentified committer, and keeps the cla-signed / cla-not-signed labels in sync with the check result. CLA signing links now point at the current forms. (#11985, #11983, #11980, #11992, #11982, #11974)
-
Distinct-values set Expectations document their observed_value contract — Documentation and JSON schemas for the distinct values set Expectations now state that observed_value is always None, and their code examples show unexpected_count and partial_unexpected_list (plus the missing-value variants) instead. (#11934)
Changes
Features
- The verification/cla-signed check is now posted by this repository's own workflows instead of a third-party app: it enumerates a pull request's committers, fails closed when it cannot confirm them, supports re-running via an @cla-bot check comment, and posts a single guiding comment naming any unsigned or unidentified committer. (#11985)
Bug fixes
- Data Docs now renders the unexpected count and index table when unexpected-index records contain only the id/pk columns, instead of failing the result page with "No group keys passed!". (#11935)
- CLA labels on a pull request are now updated in the same run that posts the CLA status, so a pull request no longer keeps a stale cla-not-signed label after signing. (#11992)
- Pinned the checkout action to v4.3.1 across workflows, restoring CI runs for contributor pull requests from forks. (#11988)
Docs
- Documented that observed_value is always None for the distinct values set Expectations, refreshed their code examples to use unexpected_count and partial_unexpected_list, and synced the published JSON schemas to match. (#11934)
Maintenance
- SqlAlchemy row-retrieval providers for map metrics (unexpected rows, unexpected index list, and unexpected index query) can now be overridden individually by a subclass without double-registering the metric; registration behavior for all existing map metrics is unchanged. (#11998)
- Updated the documentation site's dompurify dependency from 3.4.11 to 3.4.12. (#11997)
- Updated the documentation site's fast-uri dependency from 3.1.2 to 3.1.4, picking up security fixes. (#11995)
- Updated the documentation site's immutable dependency from 4.3.8 to 4.3.9, picking up security fixes. (#11996)
- Updated the documentation site's svgo dependency from 3.3.3 to 3.3.4, picking up a security fix. (#11994)
- Updated the documentation site's body-parser dependency from 1.20.4 to 1.20.6, picking up a security fix. (#11989)
- Updated the documentation site's brace-expansion dependency from 1.1.13 to 1.1.16, picking up a security fix. (#11991)
- Strengthened the tests that verify datasource lookups read their store just in time, so they now genuinely guard that behavior. (#11949)
- Updated the pre-commit ruff hook from 0.15.12 to 0.15.15. (#11895)
- Updated the documentation site's webpack-dev-server dependency from 5.2.5 to 5.2.6, picking up security fixes. (#11990)
- Updated the documentation site's websocket-driver dependency from 0.7.4 to 0.7.5. (#11977)
- Re-enabled Redshift tests in CI. (#11984)
- The verification/cla-signed status is now reported on merge-queue commits, so the required CLA check can be satisfied in the merge queue instead of hanging pending. (#11983)
- Updated the Contributor License Agreement links in CLA.md and the CLA bot message to the current signing forms. (#11982)
- Pull requests are now blocked until every committer has a valid Contributor License Agreement signature, with cla-signed / cla-not-signed labels kept in sync with the CLA status. (#11980)
- Snowflake connection tests no longer fail on a new pyOpenSSL deprecation warning raised during the TLS handshake. (#11979)
- Corrected the Contributor License Agreement form links in CLA.md. (#11974)
Contributors
Thanks to @anxkhn, @EshwarCVS.
1.19.0 (2026-07-13)
Compatibility: zstandard added (extra spark-connect)
Highlights
-
Spark 4 and ANSI mode support — Great Expectations now works with Spark 4, including ANSI mode, so you can validate Spark DataFrames on the latest Spark release without pinning to Spark 3. The
spark-connectextra now also installszstandard. (#11969)import great_expectations as gx
context = gx.get_context()
data_source = context.data_sources.add_spark(name="my_spark")
asset = data_source.add_dataframe_asset(name="my_df")
batch = asset.add_batch_definition_whole_dataframe("batch").get_batch(
batch_parameters={"dataframe": spark_df}
) -
Date-like strings stay strings in SQL value sets — Distinct-value expectations against SQL data sources no longer turn non-ISO, date-like text such as "10-20" into a date, so text bins in a
value_setcompare correctly against text columns. Only strictYYYY-MM-DDstrings are converted to dates. (#11947)import great_expectations.expectations as gxe
gxe.ExpectColumnDistinctValuesToBeInSet(
column="bin",
value_set=["10-20", "20-30"],
) -
Clearer failure for an empty regex_list —
ExpectColumnValuesToMatchRegexListnow rejects an emptyregex_listat construction time with the message "regex_list must not be empty", instead of failing later during validation with an opaque "No objects to concatenate" error. This matches the behavior ofExpectColumnValuesToNotMatchRegexList. (#11958)import great_expectations.expectations as gxe
gxe.ExpectColumnValuesToMatchRegexList(column="my_col", regex_list=[])
# pydantic.ValidationError: ... regex_list must not be empty
Changes
Features
- Added support for Spark 4, including ANSI mode. (#11969)
Bug fixes
- Fixed the broken contributing-guide link in the welcome message posted when an issue is assigned. (#11961)
ExpectColumnValuesToMatchRegexListnow fails at construction with "regex_list must not be empty" when given an empty list, instead of raising an opaque error at validation time. (#11958)- Non-ISO date-like strings such as "10-20" in a
value_setare no longer parsed into dates for SQL distinct-value expectations; only strictYYYY-MM-DDstrings are converted. (#11947)
Docs
- Expanded the Ephemeral Data Context description on the Create a Data Context page to name CI pipelines and disposable or read-only compute environments as use cases. (#11931)
Maintenance
- Removed the Codecov integration from continuous integration and from the project README; no library behavior changes. (#11971)
- Databricks test runs now authenticate with a service principal using short-lived OAuth machine-to-machine tokens instead of a stored personal access token. (#11970)
- Re-enabled the Databricks test suite and made the target catalog configurable rather than hard-coded. (#11968)
- Removed unreachable expectation helper modules and unused internal types that were not part of the public API. (#11765)
- Updated the documentation site dependency joi from 17.13.3 to 17.13.4. (#11914)
- Made the pyarrow compatibility type-ignore valid whether or not pyarrow is installed, fixing static-analysis failures; no runtime behavior change. (#11966)
- Updated the documentation site dependency dompurify from 3.4.3 to 3.4.11. (#11917)
- Moved dialect-aware column type comparison used by the type and type-list expectations into a dedicated internal module with expanded unit-test coverage; behavior is unchanged. (#11798)
- Removed unused code from the codebase. (#11717)
- Updated the documentation site dependency launch-editor from 2.12.0 to 2.14.1. (#11918)
- Added a comment-driven issue-claiming workflow (
/assign-me,/unassign-me) with automatic release of idle claims, and narrowed issue staleness to issues labeled as needing more information. (#11957) - Rewrote the contributor documentation and added structured issue, bug-report, and request-for-comment templates. (#11950)
- Snowflake connection tests now provision their own schema and table, so they no longer depend on pre-existing warehouse state or grants. (#11945)
- Skipped the broken Google Cloud SDK setup and one credential-dependent docs snippet test so the documentation test job runs again during the continuous-integration transition. (#11959)
- Replaced the broken video embed on the GX Core introduction page with a working YouTube embed of the same demo. (#11932)
- Removed broken and malformed entries from the documentation site's redirect list. (#11936)
Contributors
Thanks to @anxkhn (first contribution), @yuricavalcanti06 (first contribution).
1.18.2 (2026-06-26)
Highlights
-
Spark Connect compatibility for distinct-values expectations — Expectations that rely on a column's distinct values — including expect_column_distinct_values_to_equal_set, expect_column_distinct_values_to_contain_set, and expect_column_distinct_values_to_be_subset_of — now run successfully against a Spark Connect session (for example Databricks serverless via an
sc://URL) instead of failing with a MetricResolutionError. Classic Spark sessions behave exactly as before. (#11922)import great_expectations as gx
batch = ... # a Spark Connect-backed batch
batch.validate(
gx.expectations.ExpectColumnDistinctValuesToEqualSet(
column="color", value_set=["red", "green", "yellow"]
)
)
Changes
Bug fixes
- Distinct-values Spark metrics no longer fail with MetricResolutionError on Spark Connect sessions such as Databricks serverless, so expectations like expect_column_distinct_values_to_equal_set work there again. (#11922)
Docs
- Corrected three typos in the "Run a Validation Definition" guide in the GX Core documentation. (#11920)
Maintenance
- Suppressed a third-party NumPy 'generic' unit deprecation warning so the BigQuery test suite can be collected on Python 3.13. (#11924)
- Updated a parametrized test to pass a list instead of an iterator, fixing test collection failures with newer pytest releases. (#11921)
- Updated the documentation site's @babel/core dependency from 7.28.6 to 7.29.6. (#11925)
- Updated the documentation site's webpack-dev-server dependency from 5.2.3 to 5.2.5. (#11926)
- Updated the documentation site's http-proxy-middleware dependency from 2.0.9 to 2.0.10. (#11927)
Contributors
Thanks to @zozo123 (first contribution).
1.18.1 (2026-06-11)
Highlights
-
Data Docs now renders regex and other parameter values containing
<,>, or&correctly — Expectation parameter values are HTML-escaped before being substituted into Data Docs render templates. Previously, a regex containing angle brackets — for example the negative lookbehind(?<!\s)— was emitted raw into the HTML, where the browser treated<!as the start of a comment and silently truncated the rendered pattern. Such values now display literally in Data Docs. The public API and serialized Expectation format are unchanged; only the HTML rendering layer is affected. (#11909)gx.expectations.ExpectColumnValuesToMatchRegex(
column="my_column",
regex=r"(?<!\s)foo",
)
# The regex now appears in full in the generated Data Docs page.
Changes
Bug fixes
- Expectation parameter values containing
<,>, or&— such as regexes using a negative lookbehind — are now HTML-escaped and render correctly in Data Docs instead of being truncated or hidden. (#11909)
Docs
- Remove the GX Cloud documentation site from the docs. (#11906)
- The documentation site version label and the release version shown in docs content now read 1.18.0, matching the latest release instead of the stale 1.16.1. (#11900)
Maintenance
1.18.0 (2026-06-02)
Highlights
-
GX Cloud paths now fail immediately with a clear explanation — GX Cloud has been shut down. Constructing a
CloudDataContextdirectly, or askingget_context(...)for a cloud context (viamode="cloud",cloud_mode=True, a complete set ofcloud_*arguments, orGX_CLOUD_*environment configuration), now raises aGreatExpectationsErrorright away instead of failing later with an opaque connection error. The message states that GX Cloud has been shut down and that these entry points will be removed in great_expectations 2.0. Non-cloud usage is unchanged, and the cloud classes and parameters remain importable with unchanged signatures through the 1.x line. (#11894)import great_expectations as gx
# Raises GreatExpectationsError:
# "GX Cloud has been shut down, so this no longer functions and will be
# removed in great_expectations 2.0."
context = gx.get_context(mode="cloud")
# Non-cloud contexts still work as before
context = gx.get_context(mode="file")
Deprecations
CloudDataContextand the GX Cloud branch ofget_context(...)(thecloud_*parameters,mode="cloud",cloud_mode=True, andGX_CLOUD_*environment configuration) are deprecated and now raise an error; the cloud-only exception, store, config, and identifier symbols remain importable only as shells. Use a non-cloud context such asgx.get_context(mode="file")orgx.get_context(mode="ephemeral"). Removal in 2.0.0. (#11894)
Changes
Features
- GX Cloud has been shut down: constructing a
CloudDataContextor requesting a cloud context fromget_context(...)now raises aGreatExpectationsErrorexplaining the shutdown instead of failing with an opaque connection error. Cloud classes and parameters stay importable with unchanged signatures until they are removed in great_expectations 2.0, and non-cloud usage is unaffected. (#11894)
Maintenance
- Temporarily skip the cloud object-store documentation examples (S3, GCS, and Azure Blob, plus Athena and AWS Glue) and the BigQuery, Redshift, and Snowflake documentation tests so the documentation-snippet CI job can run while that backend infrastructure is unavailable; Trino documentation tests still run. (#11897)
- Tests marked for the Snowflake, BigQuery, Redshift, Databricks, and Athena backends are now skipped with an explicit reason while that test infrastructure is unavailable. (#11896)
- CI service container images (Spark, Postgres, MySQL, Trino, and others) are now pulled directly from Docker Hub, and the retired ECR pull-through cache and its login steps have been removed from the workflows. (#11898)
- The Microsoft Teams notification integration tests are skipped because the webhook endpoint they posted to has been decommissioned; the mocked unit tests for that action are unchanged. (#11893)
- The Snowflake type-list expectation test now accepts the length-parameterized
BINARY(8388608)observed type that the Snowflake connector reports forVARBINARYcolumns. (#11892) - Removed the unused CodeSee architecture diagram workflow and its documentation entry. (#11886)
1.17.2 (2026-05-14)
Highlights
-
SQLAlchemy 1.4 users can run uniqueness expectations again — Expectations that resolve the
column_values.unique.conditionmetric no longer fail on SQLAlchemy 1.4 withAttributeError: module 'sqlalchemy' has no attribute 'Select', restoring compatibility for dialects still pinned to SQLAlchemy 1.x (such as ClickHouse, Redshift, and Teradata). (#11876) -
Boolean options passed to pandas assets are preserved — Boolean values such as
index_col=Falsehanded toadd_csv_assetare kept as booleans instead of being silently converted to strings, so pandas interprets them as flags rather than column names. This applies to boolean options across the pandas asset types. (#11867)data_source.add_csv_asset(name="my_asset", path="data.csv", index_col=False)
Changes
Bug fixes
- Fixed an
AttributeErroron SQLAlchemy 1.4 when an expectation resolved thecolumn_values.unique.conditionmetric, restoring SQLAlchemy 1.4 compatibility for unique-value expectations. (#11876) - Boolean arguments passed to
add_csv_assetand other pandas assets, such asindex_col=False, are no longer coerced to strings and are now applied as the boolean flags pandas expects. (#11867)
Maintenance
- Updated the documentation site's mermaid dependency from 11.12.2 to 11.15.0. (#11874)
- Updated the documentation site's @babel/plugin-transform-modules-systemjs dependency from 7.28.5 to 7.29.4. (#11873)
- Updated the documentation site's fast-uri dependency from 3.1.0 to 3.1.2, picking up upstream security fixes. (#11872)
- Updated pre-commit hooks, moving ruff from v0.15.9 to v0.15.12. (#11864)
Contributors
Thanks to @ranophoenix (first contribution), @EshwarCVS (first contribution).
1.17.1 (2026-05-05)
Compatibility: pytest-split added (extra test)
Highlights
-
Data Docs now load a patched jQuery — Data Docs pages generated by Great Expectations now reference jQuery 3.7.1 instead of the vulnerable 3.4.1 (CVE-2020-11022, CVE-2020-11023). The Data Docs UI is unchanged and security scanners no longer flag GX-generated pages for this issue. (#11856)
-
Spark column names containing dots now work — Spark-backed data assets whose column names contain dots (for example
Data.Entrega) can now be used in expectations without the spurious "The column X in BatchData does not exist" error. (#11851)batch.validate(gxe.ExpectColumnValuesToNotBeNull(column="Data.Entrega")) -
Nested Spark struct paths supported in unexpected_index_column_names — Referencing a nested Spark struct path such as
Data.evt.idinunexpected_index_column_namesno longer raisesInvalidMetricAccessorDomainKwargsKeyError; unexpected rows are surfaced keyed by the full dotted path. (#11835)batch.validate(
gxe.ExpectColumnValuesToBeInSet(column="value", value_set=[1, 2]),
result_format={
"result_format": "COMPLETE",
"unexpected_index_column_names": ["Data.evt.id"],
},
) -
Compound uniqueness expectations work on Spark timestamps with Pandas 2.x —
expect_compound_columns_to_be_uniqueandexpect_select_column_values_to_be_unique_within_recordno longer fail withValueError: Passing in 'datetime64' dtype with no precision is not allowed.on Spark DataFrames that contain timestamp columns. Entries inpartial_unexpected_listare now native Python values (for exampledatetime.datetimeandNone) rather than pandas/numpy equivalents. (#11861) -
Expectation subclasses can use aliased Pydantic fields — Subclassing a built-in Expectation and declaring a field with
Field(alias=...)no longer causesValidationError: extra fields not permittedwhen validating a batch. (#11854)class MyExpectation(gxe.ExpectColumnValuesToStartWith):
regex: str = pydantic.Field(alias="pattern")
batch.validate(MyExpectation(column="name", pattern="^a"))
Changes
Bug fixes
- Data Docs pages now load jQuery 3.7.1 instead of the vulnerable jQuery 3.4.1, addressing CVE-2020-11022 and CVE-2020-11023, with no visible change to the Data Docs UI. (#11856)
- Test datasource names are now generated from UUIDs, removing a source of intermittent name-collision failures in the test suite; no library behavior changes. (#11862)
- Compound and within-record uniqueness expectations no longer fail on Spark DataFrames containing timestamp columns under Pandas 2.x, and unexpected-value lists now contain native Python values. (#11861)
- Expectation subclasses that declare a field with a Pydantic alias can now be validated without a spurious "extra fields not permitted" error. (#11854)
- Restored the documentation-snippet integration tests that broke with sqlalchemy-redshift 1.0.0: the Redshift deployment snippet no longer references removed S3 store backends, and Snowflake key-pair authentication is used where configured. (#11857)
- Expectations targeting Spark columns whose names contain dots now resolve correctly instead of reporting that the column does not exist in the batch. (#11851)
- Nested Spark struct column paths such as
Data.evt.idcan now be used for expectation columns and unexpected index columns without raising an invalid-domain-kwargs error, and results are keyed by the full dotted path. (#11835)
Docs
- The published changelog now includes the 1.17.0 release section alongside surrounding versions. (#11865)
- Integration setup pages now link to the corresponding usage pages, making it easier to move from configuring an integration to using it. (#11848)
Maintenance
- Updated the documentation site's postcss dependency from 8.5.6 to 8.5.12. (#11859)
- Continuous integration now shards and parallelizes the slowest database marker test jobs, cutting overall CI wall-clock time;
pytest-splitis now part of the development test requirements. (#11850) - Added a temporary continuous-integration trigger for pushes to a maintenance branch so workflow changes could be exercised before merge; no user-facing effect. (#11858)
- Removed the long-deprecated
Expectation._atomic_prescriptive_templatemethod and itsadd_values_with_json_schema_from_list_in_paramshelper, both deprecated in v0.15.43; use_prescriptive_templateinstead. (#11847)
1.17.0 (2026-04-22)
Compatibility: new extra singlestore
Highlights
-
SingleStore support — Great Expectations now works against SingleStore databases: SingleStoreDB is recognized as its own SQL dialect, regex and uniqueness expectations produce correct results, quoted identifiers are handled, and setup is covered in the documentation. Install with the new
singlestoreextra. (#11828, #11839, #11837, #11842)pip install 'great_expectations[singlestore]'
import great_expectations as gx
context = gx.get_context()
data_source = context.data_sources.add_sql(
name="my_singlestore",
connection_string="singlestoredb://user:password@host:3306/my_db",
) -
strict_min and strict_max now respected in expect_column_value_lengths_to_be_between on Spark and SQL — Passing
strict_min=Trueorstrict_max=Truetoexpect_column_value_lengths_to_be_betweenpreviously produced inclusive-bound results on the Spark and SQL backends. Both backends now apply strictly exclusive bounds, matching the documented semantics and the Pandas backend. Non-strict usage is unchanged. (#11834, #11836)import great_expectations.expectations as gxe
suite.add_expectation(
gxe.ExpectColumnValueLengthsToBeBetween(
column="name", min_value=2, max_value=4, strict_min=True, strict_max=True
)
) -
Timezone-aware strftime formats accepted —
ExpectColumnValuesToMatchStrftimeFormatno longer raises a validation error when the format contains%z, and the Spark implementation of the underlying metric now validates timezone-aware formats correctly. (#11812, #11817)import great_expectations.expectations as gxe
gxe.ExpectColumnValuesToMatchStrftimeFormat(
column="ts", strftime_format="%Y-%m-%d %H:%M:%S%z"
) -
Forecast store bounds used for windowed expectations — Windowed expectations now send each expectation's batch definition to the expectation-parameters endpoint, so users on the asynchronous forecast store path receive stored forecast bounds instead of falling back to inline training. Checkpoints spanning several batch definitions fetch and merge parameters for each one. (#11831)
Changes
Features
- Windowed expectations now pass their batch definition when fetching expectation parameters, so forecast store bounds are used instead of inline forecast training; checkpoints with multiple batch definitions fetch and merge parameters per definition. (#11831)
Bug fixes
expect_column_value_lengths_to_be_betweenon Spark now honorsstrict_minandstrict_max, excluding boundary lengths as documented. (#11834)expect_column_value_lengths_to_be_betweenon SQL data sources now honorsstrict_minandstrict_max, applying strictly exclusive bounds as documented. (#11836)- Fixed the Spark implementation of the strftime-format metric so timezone directives such as
%zvalidate correctly. (#11817) - Fixed regex and uniqueness expectations against SingleStoreDB by recognizing it as its own SQL dialect, and enabled SingleStore tests in continuous integration. (#11828)
- Fixed the release pipeline step that recorded contract releases, which failed because the pact command was unavailable; PyPI releases are unblocked with no end-user behavior change. (#11819)
ExpectColumnValuesToMatchStrftimeFormatno longer raises a validation error when the format string includes the%ztimezone directive. (#11812)
Docs
- Updated the Trino and BigQuery documentation, including coverage of query assets. (#11747)
- Documented that
expect_column_proportion_of_non_null_values_to_be_betweensupports a forecasted range. (#11821)
Maintenance
- Extended the retry window on the continuous-integration contract deployment check to 20 minutes so it can outwait slow provider verification. (#11846)
- SingleStore test database is now initialized as a container service rather than through a test fixture. (#11842)
- Added support for quoted identifiers when working with SingleStore data sources. (#11839)
- Removed the long-deprecated
data_context,datasource_name,batch_parameters, andbatch_kwargsarguments (and their read-only properties) from the internalBatchclass. (#11843) - Added test coverage for custom SQL expectations. (#11844)
- Added documentation for connecting to SingleStore. (#11837)
- Removed the
ColumnMetricProvideralias and its deprecation-warning metaclass, which were deprecated in favor ofColumnAggregateMetricProvider. (#11832) - Restored clean static type checking after the pyarrow 24.0.0 release began shipping type information; no runtime behavior changed. (#11838)
- Removed support for passing a plain string as
run_idtoValidator.validate(); a run identifier or dict is required. (#11826) - Contract verification now runs as its own independently retryable continuous-integration job that waits for provider verification to complete. (#11822)
- The contract deployment check no longer fails its continuous-integration job, keeping the signal visible without blocking unrelated work. (#11829)
- Resolved two denial-of-service advisories in documentation build dependencies by pinning path-to-regexp to 0.1.13 and picking up picomatch 2.3.2. (#11824)
- Resolved documentation tooling advisories by upgrading minimatch to 3.1.5 and lodash-es to 4.18.1. (#11827)
- Bumped jest-environment-jsdom to 30.3.0 in the documentation site to pick up a fixed picomatch dependency. (#11823)
- Added a contract-compatibility deployment check to the cloud test job in continuous integration and removed a dead log-collection step. (#11801)
- Bumped dompurify from 3.3.2 to 3.4.0 in the documentation site. (#11820)
1.16.1 (2026-04-15)
Changes
Features
- Added 13 consumer-driven contract tests covering datasource API gaps, including data asset deletes, Postgres table/query assets with yearly and daily column partitioners, Snowflake DSN, connection-details and key-pair connection variants, and CSV assets with a daily file-name partitioner. (#11813)
Docs
- The compatibility reference now states explicitly that Python 3.14 and later are not currently supported, alongside the supported 3.10–3.13 range. (#11784)
Maintenance
- Bumped the docs site's follow-redirects dependency from 1.15.11 to 1.16.0. (#11815)
- The PyPI publish workflow now records each released version to PactFlow's production environment so compatibility checks gate against real releases. (#11816)
- Removed the end-to-end docker-compose cloud tests, now superseded by contract tests, and dropped the associated Mercury startup steps from CI. (#11811)
- Updated pre-commit hooks, moving ruff from v0.15.4 to v0.15.9. (#11779)
- Added contract tests covering metric-run creation and the accounts/me lookup used when discovering workspaces during context initialization. (#11804)
- Added contract tests for updating a validation definition and for fetching checkpoint expectation parameters. (#11802)
- Added contract tests covering reading and saving data context variables. (#11803)
- Contract publishing from merge-queue CI runs now uses the target branch name instead of the throwaway merge-queue ref. (#11810)
- Contract tests now use fixed, isolated organization and workspace identifiers rather than environment variables, so provider verification no longer fails with authorization errors. (#11808)
- Updated contract test fixtures to match the current cloud API, including the renamed analytics and validation-results-store configuration fields, 201 responses for datasource creation, recorded request bodies, and an isolated organization and workspace. (#11797)
Contributors
Thanks to @Adeyinka1 (first contribution).
1.16.0 (2026-04-09)
Compatibility: pact-python added (extra cloud); invoke minimum 2.0.0 removed (extra test); pact-python minimum 2.0.1 → 3.1.0 (extra test)
Highlights
-
column.unique_proportionavailable in metric list runs — Metric list runs can now computecolumn.unique_proportionalongside the existing column metrics, so you can retrieve the proportion of unique values per column without a separate run. (#11786)from great_expectations.experimental.metric_repository.metrics import MetricTypes
metrics = [MetricTypes.COLUMN_UNIQUE_PROPORTION] -
Suites added to an ephemeral context now pass freshness checks —
context.suites.add(suite)now returns a suite that matches what was stored, so passing that suite straight intocontext.validation_definitions.add()in an ephemeral context no longer raises a freshness error. (#11758)suite = context.suites.add(suite)
context.validation_definitions.add(
gx.ValidationDefinition(name="vd", data=batch_definition, suite=suite)
) -
Correct
exact_matchdefault inExpectTableColumnsToMatchSetoutput — Rendered descriptions forExpectTableColumnsToMatchSetnow reflect the expectation's real default forexact_match, so the rendered text no longer contradicts how the expectation actually validates. (#11785) -
Microsoft Teams and Jira integration documentation — The documentation now covers setting up the Microsoft Teams and Jira integrations for GX notifications and issue tracking. (#11761, #11741)
-
No more unclosed-SQLite resource warnings on Python 3.13 — SQLAlchemy execution engines now dispose their connection pool when they are garbage collected, eliminating
ResourceWarning: unclosed databasenoise and the spurious failures it caused on Python 3.13. (#11766)
Deprecations
PandasDBFSDatasourceandSparkDBFSDatasourceis deprecated; use datasources backed by Unity Catalog volumes, external locations, or workspace files. Removal in 2.0.0. (#11759)
Changes
Features
- Metric list runs now support the
column.unique_proportionmetric, computed alongside other column-level metrics. (#11786) - Added an end-to-end contract test covering the full GX Cloud resource creation flow: datasource, expectation suite, validation definition, and checkpoint. (#11783)
- Added client-driven contract tests covering datasource create, read, update, and delete through the Python client. (#11754)
- Added client-driven contract tests covering expectation suite add, get, add-or-update, and delete through the Python client. (#11756)
- Added client-driven contract tests covering validation definition and checkpoint add, get, and delete through the Python client. (#11757)
- Contract testing now runs on pact-python v3, with matchers and interactions updated to the new API and the supported version range moved to 3.x. (#11769)
- Removed the legacy hand-crafted HTTP contract tests and their supporting fixtures, which are superseded by the new client-driven contract tests. (#11768)
PandasDBFSDatasourceandSparkDBFSDatasourceare now marked as deprecated, following Databricks' deprecation of DBFS; the classes still work and will be removed in a future major release. (#11759)
Bug fixes
ExpectTableColumnsToMatchSetrenderers now use the correct default value forexact_matchin their rendered output. (#11785)- Pinned the development
invokedependency to 3.0.0 to avoid a breaking change introduced in 3.0.2. (#11781) - SQLAlchemy execution engines now dispose their engine and connection pool when garbage collected, preventing unclosed-SQLite resource warnings on Python 3.13. (#11766)
- Adding a suite in an ephemeral context now returns a suite that passes later freshness checks, so using it in a validation definition no longer raises a resource freshness error. (#11758)
Docs
- Documentation code blocks now keep lines marked as hidden out of view even when line numbers are shown. (#11731)
- Added documentation for the Microsoft Teams integration. (#11761)
- Added documentation for the Jira integration. (#11741)
Maintenance
- Release-tag CI runs no longer attempt to re-publish pact contracts, unblocking tagged releases. (#11796)
- Contract tests match the
Gx-Versionrequest header with a pattern instead of a literal value, so generated contracts are stable across commits. (#11791) - Increased the SQL test connection pool size to reduce connection contention in Databricks and Snowflake test runs. (#11793)
- CI skips code and test jobs for pull requests that only change documentation, and adds a single aggregate status check for branch protection. (#11792)
- Bumped
brace-expansionfrom 1.1.12 to 1.1.13 in the documentation site dependencies. (#11777) - CI publishes pact contracts against the pull request's head commit instead of the base branch commit, so provider verification runs against the actual changes. (#11790)
- Fixed the CI pact-broker publish step so contract publishing actually succeeds and fails loudly when it cannot. (#11787)
- CI now publishes generated pact contract files to PactFlow after cloud tests pass, skipping gracefully when no contracts exist. (#11775)
- Bumped
lodashfrom 4.17.23 to 4.18.1 in the documentation site dependencies, picking up prototype-pollution and template code-injection fixes. (#11776) - Removed the unreachable
great_expectations.profilemodule and its tests as dead code. (#11763)
1.15.2 (2026-04-01)
Highlights
-
BigQuery datasource methods now surface in IDE autocomplete and type checking — The typed stub for
context.data_sourcesnow declaresadd_bigquery,update_bigquery,add_or_update_bigquery, anddelete_bigquery, so BigQuery-specific datasource methods are discoverable in editor autocomplete and recognized by type checkers instead of pushing you toward the genericadd_sqlmethod. (#11736)datasource = context.data_sources.add_bigquery(
name="my_bigquery_ds",
connection_string="bigquery://my-project/my_dataset",
) -
New how-to guide: retrieve all unexpected rows — The documentation now includes a "Retrieve all unexpected rows" guide under Run Validations, with a runnable example showing how to get the full set of unexpected rows from a validation definition, plus cross-references from the custom SQL Expectation guide and the result format reference table. (#11712)
unexpected_rows = validation_definition.get_unexpected_rows(batch_parameters={})
Deprecations
- The
run_rest_api_pact_testREST contract test helper is deprecated; use the client-driven Pact test approach built on thepact_cloud_contextfixture. Removal in 2.0.0. (#11753)
Changes
Features
- REST contract testing can now be driven from the client side: a
pact_cloud_contextfixture builds aCloudDataContextagainst the Pact mock server without real cloud credentials, a shared data-context configuration response and interaction helper are available for reuse, and the olderrun_rest_api_pact_testhelper is marked deprecated. (#11753) - BigQuery datasource methods (
add_bigquery,update_bigquery,add_or_update_bigquery,delete_bigquery) and theBigQueryDatasourcetype are now declared in the datasources type stub, so they appear in IDE autocomplete and type checking instead of requiring the genericadd_sqlmethod. (#11736)
Docs
- Added a "Retrieve all unexpected rows" how-to guide with a runnable example script, a sidebar and landing-page entry, and cross-references from the custom SQL Expectation guide and the result format reference table. (#11712)
- Applied a small documentation wording change based on engineering feedback. (#11715)
Maintenance
- Added a script that inspects the last 28 days of scheduled CI runs and generates a markdown CI health report. (#11751)
- Bumped the docs site
yamldependency from 1.10.2 to 1.10.3. (#11746) - Updated pre-commit hooks, moving ruff-pre-commit from v0.14.9 to v0.15.4. (#11582)
- Fixed three CI configuration problems: a too-short timeout for cloud services, a mismatched docs matrix key, and a malformed Spark command. (#11743)
- Bumped the docs site
flatteddependency from 3.3.3 to 3.4.2. (#11737) - Pinned localstack to 4.14.0 to restore broken CI runs. (#11740)
- Made test schema names unique so concurrent Databricks CI runs no longer clean up each other's test setup and fail with table-not-found errors. (#11733)
- Added a generic SQL datasource test harness (
GenericSQLDatasourceTestConfig) to make it easier to try out new SQL datasources. (#11718)
Contributors
Thanks to @Julian901 (first contribution).
1.15.1 (2026-03-13)
Highlights
- Documentation for Expectation history — The documentation now covers Expectation history, explaining how changes to an Expectation are tracked over time. (#11704)
Changes
Docs
- Added documentation covering Expectation history. (#11704)
Maintenance
1.15.0 (2026-03-11)
Highlights
-
Fetch all unexpected rows from an UnexpectedRowsExpectation —
ValidationDefinition.get_unexpected_rows()returns every failing row for anUnexpectedRowsExpectation, without the 200-row cap applied to validation results. Validation results also gained anExpectationValidationResult.expectationproperty and anExpectationSuiteValidationResult.batch_parametersproperty, so you can feed a failed result straight back in to retrieve its rows. (#11711)result = validation_definition.run(batch_parameters={"year": 2026, "month": 3})
for evr in result.results:
if not evr.success:
rows = validation_definition.get_unexpected_rows(
evr.expectation,
batch_parameters=result.batch_parameters,
)
if rows:
write_to_quarantine(rows) -
Documentation for SQL Server and Fabric data sources — The docs now cover creating and using SQL Server and Microsoft Fabric data sources. (#11686)
-
A single failing metric no longer fails the whole batch of metrics — When bulk metric resolution hits an error, metrics are now retried individually, so one problematic metric no longer causes every metric in the run to error. (#11708)
Changes
Features
- Added
ValidationDefinition.get_unexpected_rows()to fetch all failing rows for anUnexpectedRowsExpectationwithout the 200-row cap, plus anExpectationValidationResult.expectationproperty and anExpectationSuiteValidationResult.batch_parametersproperty for post-run workflows. (#11711)
Bug fixes
- Fixed a regression where an error in a single metric caused every metric to fail; metrics are now retried individually when bulk resolution fails. (#11708)
Docs
- Added documentation for setting up Slack alerts. (#11681)
- Added a section to the Manage Expectations documentation covering how to edit expectations using the API. (#11697)
- Updated the agent deployment documentation to explain how to set a default workspace ID. (#11709)
- Documented the new result format option in the Core docs as well as Cloud, including how
partial_unexpected_countcontrols the number of values shown inpartial_missing_list. (#11705) - Updated documentation to reflect the current Validate button behavior and removed references to the share button, which no longer exists. (#11691)
- Documented support for SQL Server and Fabric data sources. (#11686)
Maintenance
- Silenced new mypy assignment errors in the Trino compatibility module that appeared after the
trinopackage began shipping type information. (#11707) - Bumped dompurify from 3.3.1 to 3.3.2 in the documentation site dependencies. (#11706)
- Bumped svgo from 3.3.2 to 3.3.3 in the documentation site dependencies. (#11701)
- Bumped immutable from 4.3.7 to 4.3.8 in the documentation site dependencies. (#11703)
1.14.0 (2026-03-04)
Identical to 1.13.1, re-published the same day as a minor version: the release above carried a deprecation, which the minor number signals. No changes beyond 1.13.1.
1.13.1 (2026-03-04)
Highlights
-
Trust a SQL Server certificate without turning off encryption — SQL Server and Fabric data sources accept a new
trust_server_certificateoption, so you can connect to a server presenting a self-signed or otherwise untrusted certificate while keeping encryption enabled instead of weakeningencryptto "Optional". The option works with both SQL Server authentication and Entra ID. (#11694)import great_expectations as gx
context = gx.get_context()
datasource = context.data_sources.add_sql_server(
name="my_sql_server",
host="my-host",
database="my_database",
username="my_user",
password="my_password",
trust_server_certificate=True,
) -
Config variable substitution errors no longer echo secret text — When a password or secret contains a literal
$, Great Expectations no longer includes the text following the$in the resulting missing-config-variable error message, so part of the secret is not leaked in logs. The error guidance also no longer points at the retired$MY_CONFIG_VARsubstitution syntax. (#11693)
Deprecations
- The
schema_nameparameter onTableAssetandadd_table_assetis deprecated; use the schema configured on the SQL data source's connection string. Removal in 2.0.0. (#11689)
Changes
Features
- SQL Server and Fabric data sources accept a new
trust_server_certificateoption, letting you trust a self-signed or untrusted server certificate while keeping the connection encrypted, with both SQL Server authentication and Entra ID. (#11694)
Docs
- The Cloud email alert documentation now lists ServiceNow as a supported third-party service and includes
*.service-now.comin the default allowed email domains. (#11669)
Maintenance
- The
schema_nameparameter onTableAssetandadd_table_assetis deprecated; table assets now resolve their schema from the SQL data source they belong to, so specify the schema in the data source's connection configuration instead. (#11689) - Installed the SQL Server ODBC driver in the credentials-backed documentation test step so SQL Server examples in the docs are exercised in CI. (#11698)
- Added Sentry error tracking to the documentation site, initialized early enough to capture errors that occur before the page finishes loading; the DSN comes from a
SENTRY_DSNenvironment variable and no performance data is collected. (#11695) - Config variable substitution errors no longer include text that follows a literal
$in a password or secret, avoiding partial secret leakage, and their guidance no longer references the removed$MY_CONFIG_VARsyntax. (#11693) - Updated the documentation site's
qsdependency from 6.14.1 to 6.14.2. (#11660)
1.13.0 (2026-02-26)
Compatibility: altair minimum 4.2.1 → 5.0.0; new extra fabric; removed extra mssql; new extra sql-server
Highlights
-
Microsoft Fabric datasource — You can now connect to Microsoft Fabric with the new Fabric datasource, which authenticates with an Entra ID service principal. Install it with the new
fabricextra. (#11685, #11662)import great_expectations as gx
context = gx.get_context()
datasource = context.data_sources.add_fabric(
name="my_fabric",
host="my-workspace.datawarehouse.fabric.microsoft.com",
database="my_warehouse",
client_id="<client-id>",
client_secret="<client-secret>",
) -
Distinct-value set expectations now compare in the database —
ExpectColumnDistinctValuesToBeInSet,ExpectColumnDistinctValuesToContainSet, andExpectColumnDistinctValuesToEqualSetnow push set comparison into the database instead of pulling every distinct value into memory, so they stay fast and produce small results on high-cardinality columns. Results no longer include the full list of distinct values asobserved_value; instead they reportunexpected_count/partial_unexpected_listand/ormissing_count/partial_missing_list, each capped at 20 values. (#11614, #11615, #11616)import great_expectations.expectations as gxe
suite.add_expectation(
gxe.ExpectColumnDistinctValuesToBeInSet(
column="my_col",
value_set=["a", "b", "c"],
)
) -
"SQL Server" naming throughout, including the pip extra — User-facing references to MSSQL are now written as SQL Server. Install SQL Server support with the renamed extra. (#11674)
pip install 'great_expectations[sql-server]' -
pandas 3 support — The upper pin on pandas has been removed, so Great Expectations can be installed alongside pandas 3. BigQuery reads fall back to
pandas_gbq.read_gbq, and chart rendering works with pandas 3's new string dtype default (requires altair 5). (#11677) -
ExpectAI documentation for the agent — The documentation now covers ExpectAI for the agent, including its prerequisites. (#11644, #11678)
Changes
Features
ExpectColumnDistinctValuesToEqualSetnow compares the value set inside the database rather than loading all distinct values into memory. Results returnobserved_value: Nonealong withunexpected_count,partial_unexpected_list,missing_count, andpartial_missing_list(each capped at 20 values), and the rendered output marks unexpected and missing values accordingly. (#11616)ExpectColumnDistinctValuesToBeInSetnow compares the value set inside the database rather than loading all distinct values into memory. Results returnobserved_value: Nonealong withunexpected_countandpartial_unexpected_list(capped at 20 values), and the descriptive value-counts bar chart is no longer produced. (#11614)ExpectColumnDistinctValuesToContainSetnow compares the value set inside the database rather than loading all distinct values into memory. Results returnobserved_value: Nonealong withmissing_countandpartial_missing_list(capped at 20 values), and the rendered output marks missing values. (#11615)- Added a Microsoft Fabric datasource with
add_fabric(),update_fabric(), anddelete_fabric()APIs, authenticated with an Entra ID service principal. (#11685) - A top-level ORDER BY in a user-supplied query is now stripped automatically when that query is wrapped in a row count, so SQL Server no longer rejects it. ORDER BY inside window functions or nested subqueries, and queries using OFFSET, are left untouched. (#11670)
Bug fixes
- When a metric computation fails twice on a SQL Server connection, the connection is now explicitly rolled back before the error is raised, so closing the connection no longer hangs. (#11680)
- SQL expectations using the
{batch}placeholder on Databricks no longer fail with a cast error, because batch queries are now compiled with the datasource's own dialect so identifiers are quoted correctly. (#11671)
Docs
- Refined the prerequisites documentation for using ExpectAI with the agent. (#11678)
- Added documentation for using ExpectAI with the agent. (#11644)
Maintenance
- Store backend implementations that were deprecated in the v1 release, along with the documentation examples that referenced them, have been removed. (#11675)
- SQL Server column types are now reported consistently between the metric repository and
ExpectColumnValuesToBeOfType/ExpectColumnValuesToBeInTypeList, compared case-insensitively and withoutCOLLATEclauses in the type string. (#11684) - The upper pin on pandas has been removed so Great Expectations works with pandas 3, with BigQuery reads falling back to
pandas_gbq.read_gbqand chart rendering updated for the new string dtype default. (#11677) - Test helpers now build an ephemeral context via
gx.get_context(mode="ephemeral")instead of the removedbuild_in_memory_runtime_contexthelper, eliminating a source of flaky tests. (#11683) - Removed the repeated noisy
_get_default_value called with key ... but it is not a known fieldINFO log messages emitted during checkpoint validation. (#11626) - MSSQL references are now named SQL Server throughout: the pip extra is
sql-serverinstead ofmssql, and related enum members, helper names, pytest markers, and the test CLI flag were renamed to match. The SQLAlchemy dialect valuemssqlis unchanged. (#11674) - Datasource marker tests now run against a single Python version on pull requests, with the full version matrix reserved for releases. (#11666)
- Failed SQL Server connection tests now report human-readable error messages. (#11661)
- Removed Entra ID Password authentication, which Microsoft's mandatory MFA enforcement makes unusable. (#11665)
- Added a published JSON schema for the SQL Server datasource, documenting its connection-detail options. (#11662)
- Added Azure AD service principal authentication details for SQL Server connections and corrected the casing of the authentication query parameter used for Azure AD password authentication. (#11653)
1.12.3 (2026-02-13)
Highlights
-
SQL Server datasources with Azure AD password authentication — You can now connect to SQL Server with a flat set of connection keyword arguments, including Azure Active Directory password authentication, without hand-building a connection string. (#11645, #11640, #11643)
context.data_sources.add_sql_server(
name="my_sql_server",
host="my-server.database.windows.net",
database="my_db",
username="user@example.com",
password="${MY_PASSWORD}",
) -
Broader Microsoft SQL Server support — SQL Server now works with schemas, with bracket-quoted identifiers such as [my column], and with UnexpectedRowsExpectation queries. (#11649, #11652, #11646)
-
unexpected_index_query is returned for ExpectCompoundColumnsToBeUnique on SQL — ExpectCompoundColumnsToBeUnique run against SQL data sources now returns unexpected_index_query when you request it with return_unexpected_index_query=True or use the COMPLETE result format, so you can retrieve every failing row beyond the 200-row unexpected_list limit. COMPLETE also now honors return_unexpected_index_query=False when you set it explicitly. (#11639)
result = batch.validate(
ExpectCompoundColumnsToBeUnique(column_list=["a", "b"]),
result_format={"result_format": "COMPLETE"},
)
print(result.result["unexpected_index_query"]) -
pandas Timestamp values accepted in datetime comparisons — Datetime comparison expectations now handle pandas.Timestamp values correctly, checking the most specific type first so Timestamps are no longer mis-handled as plain dates. (#11637)
Changes
Features
- Dialect quoting now supports asymmetric identifier quote characters, so SQL Server bracket-quoted identifiers such as [my column] are handled correctly (double-quoted identifiers are also accepted for SQL Server). (#11652)
- SQL Server data sources now support schemas, including schema names that contain upper-case characters. (#11649)
- Added SQL Server Azure AD password authentication and a flat keyword-argument style for add_sql_server, update_sql_server, and add_or_update_sql_server, with type stubs for both calling styles. (#11645)
- UnexpectedRowsExpectation now works against SQL Server, including queries that previously relied on unsupported SQL constructs. (#11646)
- Added SQL Server type stubs and switched the integration tests to the public SQL Server datasource API. (#11643)
Bug fixes
- Datetime comparison operations now accept pandas.Timestamp values, checking Timestamp before datetime and date so timestamps are compared correctly. (#11637)
- ExpectCompoundColumnsToBeUnique on SQL data sources now returns unexpected_index_query when requested or when using the COMPLETE result format, and COMPLETE respects return_unexpected_index_query=False when explicitly set. (#11639)
- Removed the vestigial, unsupported table domain key from ExpectColumnToExist. (#11630)
Docs
- Removed documentation about the deprecated DBFS support. (#11648)
- Added documentation for adding an Expectation using the GX Cloud API. (#11567)
- Revised the contribution guidelines to encourage pull requests for new features and to clarify the acceptance criteria for contributions. (#11638)
- Added documentation for email alerts. (#11628)
- Fixed a broken documentation link to expect_table_row_count_to_equal_other_table. (#11634)
- The core result format documentation now defines the meaning of the asterisks used in its tables. (#11631)
- Added documentation describing the next steps after an agent request. (#11619)
Maintenance
- Integration tests now dispose of SQL Server connections when they finish. (#11663)
- Raised the container startup timeout used by the test suites to three minutes to reduce flaky CI failures. (#11659)
- Added a healthcheck start period and RabbitMQ readiness check to the local Mercury docker-compose stack to prevent flaky CI failures. (#11655)
- Introduced a SQLServerDatasource with structured SQL Server authentication connection details, validating that connection URLs use the mssql+pyodbc scheme and supporting config-substituted passwords. (#11640)
- Bumped webpack from 5.94.0 to 5.104.1 in the documentation site. (#11636)
- Added database-pushdown metrics for distinct-value set comparisons (column.distinct_values.not_in_set, column.distinct_values.not_in_set.count, column.distinct_values.missing_from_column, and column.distinct_values.missing_from_column.count) that evaluate set comparisons in the database instead of fetching all distinct values into memory, with type coercion for date strings. (#11629)
- Bumped diff from 3.5.0 to 3.5.1 in the documentation site. (#11627)
- Removed a duplicated flaky pandas result-format test from the test suite. (#11623)
Contributors
Thanks to @subediparas5, @teixeirazeus (first contribution).
1.11.3 (2026-01-29)
Highlights
-
Row conditions work again on SQLAlchemy 1.x data sources — Validating an expectation with a
row_conditionagainst a SQLAlchemy 1.x data source no longer fails withAttributeError: module 'sqlalchemy' has no attribute 'ColumnElement'. Row conditions now work on both SQLAlchemy 1.x and 2.x. (#11612) -
Redshift column detection works for tables in non-default schemas — Redshift assets backed by a table in a non-default schema (for example
bi_db.my_table) no longer fail column detection withrelation "my_table" does not exist; the fallback lookup is now schema-qualified. (#11606)
Changes
Bug fixes
- Using a
row_conditionwith a SQLAlchemy 1.x data source no longer raisesAttributeError: module 'sqlalchemy' has no attribute 'ColumnElement'. (#11612) - Redshift fallback column detection now schema-qualifies its query, so tables in a non-default schema no longer fail with a "relation does not exist" error. (#11606)
Docs
- Added documentation for the Atlan integration. (#11580)
- Updated links to the
airflow-provider-great-expectationsdocumentation and removed an unused CI script. (#11621)
Maintenance
Contributors
Thanks to @subediparas5 (first contribution).
1.11.2 (2026-01-22)
Compatibility: pandas minimum set to 1.3.0 (python_version >= "3.12")
Highlights
-
pandas 3.0 is excluded from supported versions — Installations now resolve a
pandasversion below 3.0.0, so environments no longer pick up an incompatible pandas 3.x release. On Python 3.12 and newer, the minimum supportedpandasversion is 1.3.0. (#11607) -
Refreshed Result format documentation — The documentation covering result format has been reworked so it is easier to find the right result format setting and understand what each one returns. (#11596)
Changes
Docs
- Reworked the result format documentation. (#11596)
Maintenance
- Constrained the supported
pandasversion to below 3.0.0. (#11607)
1.11.1 (2026-01-20)
Highlights
-
Result-format levels are now respected for Custom SQL and Multi-Source Expectations — Validation results for Custom SQL and Multi-Source Expectations no longer include row-level data at result-format levels below COMPLETE. BOOLEAN_ONLY returns only success; BASIC and SUMMARY add the observed value (Custom SQL) or unexpected count and percent (Multi-Source); unexpected and missing rows appear only with COMPLETE. Multi-Source Expectations also render correctly when the result is empty. (#11601)
-
get_context is recognized as a public export by type checkers — The top-level great_expectations module now declares its public symbols explicitly, so static type checkers such as Pyright no longer report get_context and other promoted symbols as not exported. (#11578)
import great_expectations as gx
context = gx.get_context()
Changes
Bug fixes
- Custom SQL and Multi-Source Expectation validation results now include row-level data only at the COMPLETE result format, matching the BOOLEAN_ONLY, BASIC, SUMMARY, and COMPLETE hierarchy, and Multi-Source Expectations no longer fail to render when the result is empty. (#11601)
- Added an explicit public-symbol list to the top-level great_expectations module so static type checkers recognize get_context and other promoted symbols as exported. (#11578)
- Expectation configuration equality now accounts for the Expectation ID, so suites containing multiple Expectations with identical kwargs and meta but different IDs no longer produce missing or duplicated validation results. (#11593)
Maintenance
Contributors
Thanks to @ipriyankalimbad (first contribution).
1.11.0 (2026-01-12)
Highlights
-
Unexpected rows are returned as dictionaries for Map expectations — Map expectation validation results now report
unexpected_rowsas dictionaries keyed by column name instead of database-specific row objects rendered as tuples, so results are easier to parse and no longer depend on an opt-in flag. (#11591, #11583)result = batch.validate(expectation)
# result["result"]["unexpected_rows"]
# [{"col_a": 1.0, "col_b": 1.0, "col_c": 2.0}] -
Column-based validations work on Redshift batches —
batch.columns()no longer returns an empty list for Redshift batches on clusters with restrictedinformation_schemaaccess, and table names given as"schema.table"are resolved correctly, so column-based expectations run instead of failing with a metric domain error. (#11534)batch = batch_definition.get_batch()
print(batch.columns()) -
Unexpected index query available with SUMMARY result format —
return_unexpected_index_queryis now supported with the SUMMARY result format, matching what BASIC already offered. (#11594)result = batch.validate(
expectation,
result_format={
"result_format": "SUMMARY",
"unexpected_index_column_names": ["pk"],
"return_unexpected_index_query": True,
},
)
Changes
Features
- Map expectation validation results now serialize
unexpected_rowsas dictionaries by default, and themap_expectation_unexpected_rows_as_dictopt-in flag is no longer needed. (#11591)
Bug fixes
- Fixed
batch.columns()returning an empty list for Redshift batches, which caused column-based expectations to fail; column names are now retrieved via a fallback query wheninformation_schemais inaccessible, andtable_namevalues of the form"schema.table"are parsed correctly. (#11534)
Docs
- Documentation no longer labels ExpectAI as beta. (#11590)
- Removed temporary notes about row conditions from the documentation. (#11581)
- The copy button on documentation code blocks no longer copies hidden lines. (#11571)
- Reframed and clarified the documented Data Source limitations. (#11570)
Maintenance
return_unexpected_index_queryis now supported with the SUMMARY result format, so SUMMARY is no longer more limited than BASIC. (#11594)- Suppressed
DeprecationWarnings emitted by dependencies so local test runs are not failed by them. (#11587) - Added an opt-in
map_expectation_unexpected_rows_as_dictCheckpoint setting that serializesunexpected_rowsas dictionaries for all Map expectations on SQLAlchemy and Spark, with the default output unchanged. (#11583) invoke depsaccepts--ptyand--no-ptyflags so automated environments can control pseudo-terminal usage. (#11586)- Improved the local type-checking developer experience: fixed type errors, silenced
pyparsingdeprecation warnings via the compatibility layer, and documented the type-checking workflow so local runs match CI. (#11574)
Contributors
Thanks to @leodrivera (first contribution).
1.10.0 (2025-12-18)
Highlights
-
Unexpected-index columns and unexpected queries on BOOLEAN_ONLY and BASIC result formats — Result formats BOOLEAN_ONLY and BASIC now support returning primary-key/unexpected-index columns and the unexpected-rows query, so you can identify failing rows without switching to a more verbose result format. (#11563)
result = batch.validate(
expectation,
result_format={
"result_format": "BASIC",
"unexpected_index_column_names": ["pk_1"],
},
)
Changes
Features
- BOOLEAN_ONLY and BASIC result formats now support unexpected-rows queries and primary-key/unexpected-index columns. (#11563)
Docs
- Documented metric filters for the data health dashboard. (#11529)
- Documented result format options for GX Cloud. (#11558)
- Removed a temporary note about severity from the documentation. (#11564)
Maintenance
- Suppressed a noisy Google library warning about running on Python 3.10. (#11572)
- Continuous integration no longer fails when uploading coverage or test results to Codecov fails, reducing flaky builds. (#11569)
- Bumped the pinned ruff linter version from 0.14.8 to 0.14.9 in development requirements and pre-commit. (#11568)
- Fixed a flaky SQLite ResourceWarning in the test suite by closing connections deterministically during teardown. (#11562)
- Corrected the add_dataframe_asset docstring for Spark datasources. (#11561)