Fixes #28077: [SNOWFLAKE INGESTION METADATA] Duplicate column case - #32500
Conversation
Snowflake allows a table to hold columns whose names only differ in their casing (e.g. "Hotel_region" and HOTEL_REGION). The ORM converter keys every SQA column by its lowercase name, so those columns collided in the table's column collection: one of them was dropped and the declarative mapper failed with "column <table>.<column> is not represented in the mapper's table", aborting the whole profiler/data quality workflow. Keep the original name as the SQA key when the lowercase name is ambiguous, so every column is mapped and can be profiled or tested. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Code Review ✅ ApprovedFixes duplicate column case sensitivity issue in Snowflake ingestion by preserving original column names as keys when they differ only in casing. The fix updates OptionsDisplay: compact → Showing less information. Comment with these commands to change the behavior for this request:
Was this helpful? React with 👍 / 👎 | Powered by Gitar — free for open source |
There was a problem hiding this comment.
🟢 Approval recommended
The fix directly addresses the reported mapper failure mode and includes a targeted regression unit test that exercises the corrected behavior.
Pull request overview
This PR fixes Snowflake ingestion/profiler failures when a table contains two columns that differ only by casing (e.g., "Hotel_region" and HOTEL_REGION), which previously collided due to lowercased SQLAlchemy column keys and caused ORM mapper configuration errors.
Changes:
- Add
build_orm_col_keys()to compute per-column SQLAlchemykeyvalues that remain unique when case-insensitive collisions occur. - Update
ometa_to_sqa_orm()to pass the computed per-columnkeyintobuild_orm_col(), preventing column eviction from SQLAlchemy’s column collection. - Add a unit regression test covering the case-only-different duplicate column scenario for Snowflake.
File summaries
| File | Description |
|---|---|
| ingestion/src/metadata/profiler/orm/converter/base.py | Computes unique SQLAlchemy column keys to avoid case-insensitive collisions and wires them into ORM generation. |
| ingestion/tests/unit/observability/profiler/test_converter.py | Adds a regression unit test ensuring both case-variant columns are preserved and keyed safely. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
✅ Playwright Results — workflow succeededValidated commit ✅ 109 passed · ❌ 0 failed · 🟡 1 flaky · ⏭️ 0 skipped · 🧰 0 lifecycle flaky PerformanceBlocking targets: ✅ met · Optimization targets: 🟡 in progress Shard-job maxima below are not the full workflow wall time; the linked run includes build, fixture, planning, and reporting. 🕒 Full workflow signal wall (to summary) 53m 47s ⏱️ Max setup 6m 33s · max shard execution 13m 3s · max shard-job elapsed before upload 20m 5s · reporting 5s 🌐 219.35 requests/attempt · 1.78 app boots/UI scenario · 0.00% common-shard skew Optimization targets still in progress:
🟡 1 flaky test(s) (passed on retry)
How to debug locally# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip # view trace |
| ) | ||
|
|
||
|
|
||
| def build_orm_col_keys(columns: list[Column]) -> list[str]: |
There was a problem hiding this comment.
build_orm_col still defaults to name.lower() when no key= is passed, and the Athena/Databricks profiler interfaces rebuild the columns after ometa_to_sqa_orm without it (athena/profiler_interface.py:106, databricks/profiler_interface.py:146) — __table__.c drops back to 2 keys there and Hotel_region gets evicted. Moving the key computation into a shared build_orm_cols(columns, service_type) would stop callers forgetting it.
| quote=quote, | ||
| key=str(col.name.root).lower(), # Add lowercase column name as key for snowflake case sensitive columns | ||
| # Add lowercase column name as key for snowflake case sensitive columns | ||
| key=key or str(col.name.root).lower(), |
There was a problem hiding this comment.
| key=key or str(col.name.root).lower(), | |
| key=key if key is not None else str(col.name.root).lower(), |
Also, build_orm_col_keys could use a direct test (e.g. ["Foo", "FOO", "foo"]).
🚦 Removed from the merge queue —
|



What olivaw checked (machine-observed, §8.2/A.1)
77cae1608394c14e81054e8f6aab9c2a3e1eb99966827ec5ef5c10a355dc3290cab501d1add4e33bNo build or test command is configured for this workspace, so only the diff's existence was checked. Set
run_config.build_cmd/test_cmdto have olivaw verify its own work.What the agent says it did (unverified)