github snowflakedb/snowflake-sqlalchemy v2.0.0a2
Release

2 hours ago
  • v2.0.0a2 (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_json now defaults to True (was False); explicitly setting it to False emits a DeprecationWarning (SNOW-3942921).
    • force_div_is_floordiv now defaults to False (was True); explicitly setting it to True emits a DeprecationWarning (SNOW-3942921).
    • legacy_url_params (and its SNOWFLAKE_SQLALCHEMY_LEGACY_URL_PARAMS environment variable) removed; passing it now raises ArgumentError (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) in get_multi_indexes result keys so indexes attach when reflecting under the default schema, and return [] instead of [''] for empty INCLUDE columns (GH #755, fixes GH #754).
    • Add COLLATE support: expression-level Column.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 suite CollateTest (SNOW-629086).
    • Add subscript access for semi-structured columns: col["key"] and col[index] on VARIANT, OBJECT, ARRAY and MAP columns now compile to Snowflake's native bracket accessor (e.g. col['key'], col[0]), including nested chains such as col["a"]["b"]. See Reading keys and elements with subscript access (SNOW-1820647 / GH #546).
    • Add opt-in enable_structured_type_json dialect flag (URL parameter or create_engine(..., enable_structured_type_json=True)). When enabled, for semi-structured (untyped) VARIANT, OBJECT and ARRAY columns: reading deserializes the JSON text Snowflake returns into native Python (dict/list/...), and writing native dict/list values serializes them and wraps them in PARSE_JSON — rendered as INSERT ... SELECT (single row and multi-row UNION ALL) since Snowflake rejects functions in a VALUES clause, and as SET col = PARSE_JSON(...) for UPDATE. Typed/structured columns (OBJECT(...) with fields, ARRAY(<type>), MAP) keep their native connector handling. The engine's json_serializer/json_deserializer are 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 in is_disconnect, so pool_pre_ping / connection_invalidated recover from it like the other token/session-loss codes (SNOW-3882904 / GH #702).
    • Support asdecimal parameter on _CUSTOM_DECIMAL type 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 own parse_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 FIRST statements via the new InsertMulti custom command, including conditional (when/else_), OVERWRITE, and per-target column/value mapping (SNOW-782235 / GH #403).
    • Add support for row access policies on SnowflakeTable via the row_access_policy parameter; the policy name accepts a string (optionally fully qualified, e.g. 'db.schema.policy') or a snowflake.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 SHOW commands (get_table_names, get_view_names, get_temp_table_names, get_schema_names, get_sequence_names) with LIMIT ... FROM ... (SNOW-796954 / GH #406).
    • Add opt-in snowflake_rely=True to render RELY on PRIMARY KEY / FOREIGN KEY / UNIQUE constraints so the optimizer can trust them for query rewrites such as join elimination (SNOW-1023317 / GH #463).
    • Add a python_type property to Snowflake custom types (VARIANT, OBJECT, MAP, ARRAY, VECTOR, TIMESTAMP_*, GEOGRAPHY, GEOMETRY, DECFLOAT) for SQLAlchemy compatibility (SNOW-1866493 / GH #562).
    • Fix URL failing to encode [, ], ? and # in passwords, which produced connect strings that could not be parsed (SNOW-828206 / GH #415).
    • Enhance JSONFormatter with the full Snowflake TYPE=JSON option 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_serializer and json_deserializer parameters in create_engine, matching the built-in SQLAlchemy dialects (SNOW-889293 / GH #433).
    • Detect expired-session/token and closed-connection errors as disconnects so connection_invalidated is set and pooled connections are recycled (SNOW-669163 / GH #348).
    • Add if_not_exists and comment options to CreateFileFormat for closer parity with Snowflake's CREATE FILE FORMAT (SNOW-589962 / GH #291).
    • Document SSO/Okta authentication via the authenticator connect_args parameter (SNOW-715550).
    • Document how to enable connector bulk array binding for large executemany inserts via qmark paramstyle (SNOW-710474).
    • Document using a SQLAlchemy VALUES source with MergeInto (no staging table needed) (SNOW-889678 / GH #435).
    • Document writing dicts/lists to VARIANT/OBJECT/ARRAY via INSERT ... SELECT with PARSE_JSON (SNOW-801402 / GH #411).
    • Document the raw-connector workaround for PUT with an in-memory file_stream (BytesIO) (SNOW-645168 / #337).
    • Document CLUSTER BY usage in ORM/declarative models via SnowflakeTable (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; use col == true()/col == false() (#680).
    • Fix invalid LIMIT -1 SQL generated for a SELECT with OFFSET but no LIMIT; the SnowflakeCompiler now emits LIMIT NULL OFFSET ... as Snowflake requires (NO-SNOW / GH #745).
  • v2.0.0a2 (Unreleased)

Don't miss a new snowflake-sqlalchemy release

NewReleases is sending notifications on new releases.