Skip to content

Commit 261ad38

Browse files
Merge branch 'main' into jcieslak/add-query-tag-support
# Conflicts: # DESCRIPTION.md # pyproject.toml
2 parents 1b2cbae + b95de49 commit 261ad38

16 files changed

+594
-154
lines changed

DESCRIPTION.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@ Source code is also available at:
1313
- Add server_version_info support
1414
- Add support for `ILIKE` in queries
1515
- Fix `SYSDATE()` rendering
16+
- Fix and improve schema reflection (SNOW-593204, SNOW-2331576, SNOW-2852779)
17+
- Fix crash when reflecting without specifying a schema, caused by `None` arguments in internal schema resolution ([#623](https://github.com/snowflakedb/snowflake-sqlalchemy/issues/623)).
18+
- Fix crash when `SHOW TABLES` returns empty string table names, causing `IndexError` during reflection ([#296](https://github.com/snowflakedb/snowflake-sqlalchemy/issues/296)).
19+
- Fix incomplete identity column reflection metadata, now includes all fields required by SQLAlchemy 2.0+ (`always`, `cycle`, `order`, etc.).
20+
- Introduce shared helper for fully-qualified schema name resolution, replacing inconsistent ad-hoc patterns across reflection methods.
21+
- Refactor column reflection internals into dedicated helpers to reduce complexity without changing behavior.
22+
- Add `pytest-xdist` parallel test support via per-worker schema provisioning hooks.
23+
- Bump `pandas` lower bound in `sa14` test environment from `<2.1` to `>=2.1.1,<2.2` to ensure pre-built wheels are available for Python 3.12
24+
- Fix SQLAlchemy version parsing (SNOW-3066571)
1625
- Document support for session parameters (like [QUERY_TAG](https://docs.snowflake.com/en/sql-reference/parameters#query-tag)), references: [#644](https://github.com/snowflakedb/snowflake-sqlalchemy/issues/495)
1726

1827
# Release Notes

ci/test_linux.sh

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
# - This is the script that test_docker.sh runs inside of the docker container
88

99
PYTHON_VERSIONS="${1:-3.8 3.9 3.10 3.11 3.12 3.13 3.14}"
10+
# Python versions where pyarrow (required by pandas extra) is not available
11+
PANDAS_SKIP_VERSIONS="3.14"
1012
THIS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
1113
SQLALCHEMY_DIR="$(dirname "${THIS_DIR}")"
1214

@@ -19,7 +21,12 @@ for PYTHON_VERSION in ${PYTHON_VERSIONS}; do
1921
echo "[Info] Testing with ${PYTHON_VERSION}"
2022
SHORT_VERSION=$(python3 -c "print('${PYTHON_VERSION}'.replace('.', ''))")
2123
SQLALCHEMY_WHL=$(ls $SQLALCHEMY_DIR/dist/snowflake_sqlalchemy-*-py3-none-any.whl | sort -r | head -n 1)
22-
TEST_ENVLIST=fix_lint,py${SHORT_VERSION}-ci,py${SHORT_VERSION}-coverage,py${SHORT_VERSION}-pandas-ci,py${SHORT_VERSION}-pandas-coverage
24+
TEST_ENVLIST=fix_lint,py${SHORT_VERSION}-ci
25+
if [[ ! " ${PANDAS_SKIP_VERSIONS} " =~ " ${PYTHON_VERSION} " ]]; then
26+
TEST_ENVLIST="${TEST_ENVLIST},py${SHORT_VERSION}-pandas-ci"
27+
else
28+
echo "[Info] Skipping pandas tests for Python ${PYTHON_VERSION} (pyarrow not available)"
29+
fi
2330
echo "[Info] Running tox for ${TEST_ENVLIST}"
24-
python3 -m tox -e ${TEST_ENVLIST} --installpkg ${SQLALCHEMY_WHL}
31+
python3 -m tox -p auto -e ${TEST_ENVLIST} --installpkg ${SQLALCHEMY_WHL}
2532
done

pyproject.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ development = [
5555
"pytest-xdist",
5656
"pytz",
5757
"numpy",
58-
"mock",
5958
"syrupy",
6059
]
6160
pandas = ["snowflake-connector-python[pandas]"]
@@ -85,7 +84,11 @@ installer = "uv"
8584
[tool.hatch.envs.sa14]
8685
installer = "uv"
8786
builder = true
88-
extra-dependencies = ["SQLAlchemy>=1.4.19,<2.0.0", "pandas>=2.1.1,<2.2", "numpy<2"]
87+
extra-dependencies = [
88+
"SQLAlchemy>=1.4.19,<2.0.0",
89+
"pandas>=2.1.1,<2.2",
90+
"numpy<2",
91+
]
8992
features = ["development", "pandas"]
9093
python = "3.12"
9194

@@ -142,4 +145,5 @@ markers = [
142145
"external: tests that could but should only run on our external CI",
143146
"feature_max_lob_size: tests that could but should only run on our external CI",
144147
"feature_v20: tests that could but should only run on SqlAlchemy v20",
148+
"mypy: typing tests",
145149
]

src/snowflake/sqlalchemy/compat.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
string_types = (str,)
1212
returns_unicode = util.symbol("RETURNS_UNICODE")
1313

14-
IS_VERSION_20 = tuple(int(v) for v in SA_VERSION.split(".")) >= (2, 0, 0)
14+
IS_VERSION_20 = tuple(int(v) for v in SA_VERSION.split(".")[:2]) >= (2, 0)
1515

1616

1717
def args_reducer(positions_to_drop: tuple):

src/snowflake/sqlalchemy/provision.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,32 @@
11
#
22
# Copyright (c) 2012-2023 Snowflake Computing Inc. All rights reserved.
33
#
4-
from sqlalchemy.testing.provision import set_default_schema_on_connection
4+
from sqlalchemy.testing.provision import (
5+
create_db,
6+
drop_db,
7+
set_default_schema_on_connection,
8+
)
9+
10+
11+
@create_db.for_db("snowflake")
12+
def _snowflake_create_db(cfg, eng, ident):
13+
"""Create a schema for the xdist worker.
14+
15+
For Snowflake, we create schemas instead of databases since:
16+
- Creating databases requires admin privileges
17+
- Schema-level isolation is sufficient for test isolation
18+
- The schema name becomes the 'ident' (e.g., test_schema_gw0)
19+
"""
20+
with eng.begin() as conn:
21+
# Create schema if it does not already exist
22+
conn.exec_driver_sql(f"CREATE SCHEMA IF NOT EXISTS {ident}")
23+
24+
25+
@drop_db.for_db("snowflake")
26+
def _snowflake_drop_db(cfg, eng, ident):
27+
"""Drop the schema created for the xdist worker."""
28+
with eng.begin() as conn:
29+
conn.exec_driver_sql(f"DROP SCHEMA IF EXISTS {ident}")
530

631

732
# This is only for test purpose required by Requirement "default_schema_name_switch"

0 commit comments

Comments
 (0)