- v2.0.0a1 (Aug 20, 2026)
- Breaking change: raise the minimum supported Python to 3.10 (drop Python 3.9). Updates
requires-python, the CI/build matrices, and mypy/ruff targets accordingly. enable_structured_type_jsonnow defaults toTrue(wasFalse); explicitly setting it toFalseemits aDeprecationWarning(SNOW-3942921).force_div_is_floordivnow defaults toFalse(wasTrue); explicitly setting it toTrueemits aDeprecationWarning(SNOW-3942921).legacy_url_params(and itsSNOWFLAKE_SQLALCHEMY_LEGACY_URL_PARAMSenvironment variable) removed; passing it now raisesArgumentError(SNOW-3942921).- Fix hybrid table index reflection: normalize reflected index names so unquoted identifiers round-trip in SQLAlchemy's lowercase convention (quoted/case-sensitive names preserved), preserve the caller's original schema (including
None) inget_multi_indexesresult keys so indexes attach when reflecting under the default schema, and return[]instead of['']for emptyINCLUDEcolumns (GH #755, fixes GH #754). - Add
COLLATEsupport: expression-levelColumn.collate('<spec>')and column-type collation (String(collation='<spec>')) now render the collation as a single-quoted Snowflake string literal (e.g.COLLATE 'en-ci') instead of an invalid double-quoted identifier. Enables the SQLAlchemy suiteCollateTest(SNOW-629086). - Add subscript access for semi-structured columns:
col["key"]andcol[index]onVARIANT,OBJECT,ARRAYandMAPcolumns now compile to Snowflake's native bracket accessor (e.g.col['key'],col[0]), including nested chains such ascol["a"]["b"]. See Reading keys and elements with subscript access (SNOW-1820647 / GH #546). - Add opt-in
enable_structured_type_jsondialect flag (URL parameter orcreate_engine(..., enable_structured_type_json=True)). When enabled, for semi-structured (untyped)VARIANT,OBJECTandARRAYcolumns: reading deserializes the JSON text Snowflake returns into native Python (dict/list/...), and writing nativedict/listvalues serializes them and wraps them inPARSE_JSON— rendered asINSERT ... SELECT(single row and multi-rowUNION ALL) since Snowflake rejects functions in aVALUESclause, and asSET col = PARSE_JSON(...)forUPDATE. Typed/structured columns (OBJECT(...)with fields,ARRAY(<type>),MAP) keep their native connector handling. The engine'sjson_serializer/json_deserializerare used when provided. Off by default, so existing code that reads raw JSON strings or writes pre-serialized values is unchanged (SNOW-1820647 / GH #107). - Treat error code
390195(authentication token expired, variant) as a session disconnect inis_disconnect, sopool_pre_ping/connection_invalidatedrecover from it like the other token/session-loss codes (SNOW-3882904 / GH #702). - Support
asdecimalparameter on_CUSTOM_DECIMALtype to allow opt-in conversion of numeric results to float instead of Decimal; default remains Decimal for backward compatibility (SNOW-728151 / GH #373). - Fix PrivateLink/regional account parsing where org-style accounts with dashes (e.g.,
gnamsrm-vi65876.privatelink) were incorrectly truncated at the dash, breaking JWT/key-pair authentication. Account derivation now delegates to the Snowflake Connector's ownparse_account, so all host notations (plain, regional, regional/regionless PrivateLink, and.global) match the driver (SNOW-730644, also fixes SNOW-1209099). - Add support for Snowflake's multi-table
INSERT ALL/INSERT FIRSTstatements via the newInsertMulticustom command, including conditional (when/else_),OVERWRITE, and per-target column/value mapping (SNOW-782235 / GH #403). - Add support for row access policies on
SnowflakeTablevia therow_access_policyparameter; the policy name accepts a string (optionally fully qualified, e.g.'db.schema.policy') or asnowflake.sqlalchemy.FQN. See Row Access Policy Support (SNOW-884382 / GH #432). - Fix reflection failing on schemas/databases with more than 10,000 objects by paginating the underlying object-listing
SHOWcommands (get_table_names,get_view_names,get_temp_table_names,get_schema_names,get_sequence_names) withLIMIT ... FROM ...(SNOW-796954 / GH #406). - Add opt-in
snowflake_rely=Trueto renderRELYonPRIMARY KEY/FOREIGN KEY/UNIQUEconstraints so the optimizer can trust them for query rewrites such as join elimination (SNOW-1023317 / GH #463). - Add a
python_typeproperty to Snowflake custom types (VARIANT,OBJECT,MAP,ARRAY,VECTOR,TIMESTAMP_*,GEOGRAPHY,GEOMETRY,DECFLOAT) for SQLAlchemy compatibility (SNOW-1866493 / GH #562). - Fix
URLfailing to encode[,],?and#in passwords, which produced connect strings that could not be parsed (SNOW-828206 / GH #415). - Enhance
JSONFormatterwith the full SnowflakeTYPE=JSONoption set (date_format,time_format,timestamp_format,binary_format,trim_space,null_if,enable_octal,allow_duplicate,strip_outer_array,strip_null_values,replace_invalid_characters,ignore_utf8_errors,skip_byte_order_mark) (SNOW-589946). - Support
json_serializerandjson_deserializerparameters increate_engine, matching the built-in SQLAlchemy dialects (SNOW-889293 / GH #433). - Detect expired-session/token and closed-connection errors as disconnects so
connection_invalidatedis set and pooled connections are recycled (SNOW-669163 / GH #348). - Add
if_not_existsandcommentoptions toCreateFileFormatfor closer parity with Snowflake'sCREATE FILE FORMAT(SNOW-589962 / GH #291). - Document SSO/Okta authentication via the
authenticatorconnect_args parameter (SNOW-715550). - Document how to enable connector bulk array binding for large
executemanyinserts viaqmarkparamstyle (SNOW-710474). - Document using a SQLAlchemy
VALUESsource withMergeInto(no staging table needed) (SNOW-889678 / GH #435). - Document writing dicts/lists to VARIANT/OBJECT/ARRAY via
INSERT ... SELECTwithPARSE_JSON(SNOW-801402 / GH #411). - Document the raw-connector workaround for
PUTwith an in-memoryfile_stream(BytesIO) (SNOW-645168 / #337). - Document
CLUSTER BYusage in ORM/declarative models viaSnowflakeTable(SNOW-638838 / #313). - Document AUTOINCREMENT and IDENTITY column usage, including Sequence vs Identity trade-offs for Hybrid tables (SNOW-1232362).
- Document that Snowflake lacks
IS TRUE/IS FALSE; usecol == true()/col == false()(#680). - Fix invalid
LIMIT -1SQL generated for aSELECTwithOFFSETbut noLIMIT; theSnowflakeCompilernow emitsLIMIT NULL OFFSET ...as Snowflake requires (NO-SNOW / GH #745).
- Breaking change: raise the minimum supported Python to 3.10 (drop Python 3.9). Updates