SNOW-1232488 feat case sensitive support#675
Merged
Merged
Conversation
0cd98e6 to
2bf40d2
Compare
2bf40d2 to
2a50e39
Compare
2a50e39 to
1e240ea
Compare
sfc-gh-jcieslak
approved these changes
Apr 22, 2026
sfc-gh-jcieslak
approved these changes
Apr 23, 2026
c0aeb15 to
03ee95d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Please answer these questions before submitting your pull requests. Thanks!
What GitHub issue is this PR addressing? Make sure that there is an accompanying issue to your PR.
Fixes SNOW-1232488
Fill out the following pre-review checklist:
Please describe how your code solves the related issue.
Fix case-sensitive identifier handling (SNOW-1232488)
Fixes #[issue]
Background
Snowflake stores unquoted identifiers in uppercase (
mytable → MYTABLE). SQLAlchemy's dialect normalises names on the way in (MYTABLE → mytable) and denormalises on the way out (mytable → MYTABLE). Three bugs in this round-trip silently corrupted case-sensitive identifiers, and there was no supported way to opt into correct handling of mixed-case quoted names.What changed
Bug fixes (always active):
denormalize_column_nameinbase.py— now correctly emits double-quoted SQL forquoted_name("mycol", True)columns inCLUSTER BYclauses. Previously thequote=Truesignal was dropped and the column was silently rendered unquoted._has_object in snowdialect.py— now applies denormalize_name before building theDESC TABLEstatement, makinghas_table/has_sequenceconsistent with all other reflection methods._split_schema_by_dotinbase.py— now preservesquote=Trueon inner-quoted schema parts during dot-splitting, preventing normalisation loss for schemas like"myDb"."mySchema".New opt-in flag —
case_sensitive_identifiers:Pass as a
create_enginekeyword or?case_sensitive_identifiers=trueURL parameter. When enabled, ALL-UPPERCASE reserved-word identifiers (e.g. a column literally namedTABLE) are normalised toquoted_name("table", True)instead of being returned unchanged, preventing key-lookup mismatches between object creation and reflection.New helpers:
create_snowflake_engine(url, schema=..., case_sensitive_schema=True)— URL-encodes case-sensitive schema names via%22so the Snowflake connector receives the correct double-quoted form.snowflake.sqlalchemy.alembic_util.render_item— a drop-in Alembicrender_itemhook forenv.pythat serialisesquoted_namecolumns correctly in generated migration files, preventing autogenerate from silently uppercasing case-sensitive column names.Test infrastructure:
--case-sensitivepytest flag to run the entire integration suite with the flag enabled for local debugging.engine_testaccount_case_sensitivefixture for targeted case-sensitive integration tests in CI.test_begin_read_commited— buffer flush aftercreate_allprevents DDL COMMITs from polluting transaction count assertions.Scope
No changes to default normalisation behaviour. All fixes behind the
case_sensitive_identifiersflag are additive. Existing applications are unaffected unless they explicitly opt in.