fix: map MONEY and BIT columns to concrete SQLAlchemy types in profiler (#29459)#30210
Conversation
…open-metadata#29459) CommonMapTypes._TYPE_MAP had no entries for DataType.MONEY or DataType.BIT, so any column classified as one of these types (e.g. MSSQL's MONEY/BIT columns) fell back to CustomTypes.UNDETERMINED. That fallback type is in the profiler's NOT_COMPUTE set (profiling is skipped) and renders sample data as the literal string "OPENMETADATA_UNDETERMIND[value]" instead of the actual value. Map DataType.MONEY to sqlalchemy.NUMERIC (consistent with the existing SMALLMONEY -> NUMBER -> NUMERIC path) and DataType.BIT to sqlalchemy.BOOLEAN, and mirror both in the reverse SQA-to-OM type map.
❌ PR checklist incompleteThis PR cannot be merged until the following are addressed on its linked issue:
The fields live on the linked issue in the Shipping project (open the issue → right sidebar → Projects). After you set them, re-run this check (or push a commit) — issue/project changes do not re-trigger it automatically. Maintainers can bypass this check by adding the |
|
Hi there 👋 Thanks for your contribution! The OpenMetadata team will review the PR shortly! Once it has been labeled as Let us know if you need any help! |
Code Review ✅ ApprovedMaps MONEY and BIT types to NUMERIC and BOOLEAN in the profiler converter, resolving silent profiling skips and incorrect data rendering. No issues found. OptionsDisplay: compact → Showing less information. Comment with these commands to change the behavior for this request:
Was this helpful? React with 👍 / 👎 | Gitar |
Fixes #29459
Root cause
CommonMapTypes._TYPE_MAPiningestion/src/metadata/profiler/orm/converter/common.pyhad no entries for
DataType.MONEYorDataType.BIT.return_custom_type()falls back to
CustomTypes.UNDETERMINED.value(UndeterminedType) for anydataTypenot present in the map. That fallback type:NOT_COMPUTEset (profiler/orm/registry.py), so profilingis silently skipped for these columns, and
UndeterminedType.process_result_valueas the literalstring
OPENMETADATA_UNDETERMIND[value](exactly matching the screenshots inthe issue).
SMALLMONEYalready worked because it's classified as OMDataType.NUMBER(see
column_type_parser.py), which does have a_TYPE_MAPentry.MONEYandBITare their ownDataTypeenum values with no corresponding entry, so theyhit the undetermined fallback regardless of which connector reports them —
this isn't MSSQL-specific, just most commonly hit there.
What changed
DataType.MONEY: sqlalchemy.NUMERICandDataType.BIT: sqlalchemy.BOOLEANto
CommonMapTypes._TYPE_MAP.map_sqa_to_om_types()map (merged into theexisting
sqlalchemy.NUMERIC/sqlalchemy.BOOLEANentries rather thanadding duplicate dict keys).
Test evidence
Added
test_money_and_bit_types_are_mappediningestion/tests/unit/observability/profiler/test_converter.py, building anORM table with
MONEYandBITcolumns (MSSQL service type) viaometa_to_sqa_ormand asserting the resulting SQLAlchemy column types areNUMERIC/BOOLEAN, notUndeterminedType. Verified fail → pass locally:assert not isinstance(amount_type, undetermined_type)fails —
AssertionError: assert not True.Ran the full
tests/unit/observability/profiler/suite (excludingdirectories that need optional connector deps not part of the
test-unitextra —
pandas,sqlalchemy_bigquery,pyathena— not installable in thisenvironment due to an unrelated
cx_Oracle/pkg_resourcesbuild failureunder the
testextra): 356 passed, 1 skipped, only pre-existingenvironment-only failures unrelated to this change (missing
pandas/sqlalchemy_bigquerymodules).ruff checkandruff format --checkare clean on both touched files.Prepared with AI assistance (Claude Code, Anthropic), reviewed for correctness before submission.
Greptile Summary
This PR fixes profiling being silently skipped for
MONEYandBITcolumns by adding the two missingDataTypeentries toCommonMapTypes._TYPE_MAPand mirroring them in the reversemap_sqa_to_om_types()map. Without the fix, these columns fell through toUndeterminedType, which is in theNOT_COMPUTEset and renders sample data as the literal stringOPENMETADATA_UNDETERMIND[value].DataType.MONEYis now mapped tosqlalchemy.NUMERIC(forward) and included in theNUMERICreverse-map set, enabling numeric metric computation on MONEY columns.DataType.BITis now mapped tosqlalchemy.BOOLEAN(forward) and included in theBOOLEANreverse-map set.test_money_and_bit_types_are_mappedverifies both columns resolve to the correct SQLAlchemy types instead ofUndeterminedTypewhen building ORM tables viaometa_to_sqa_orm.Confidence Score: 5/5
Safe to merge; the two-line change to _TYPE_MAP and matching reverse-map update are isolated and well-tested with no risk to existing mappings.
The change is minimal: two entries added to a dict, two existing sets expanded. The fix is applied in CommonMapTypes, so it is inherited by all dialect-specific subclasses (including MssqlMapTypes, AzureSqlMapTypes, etc.) without needing per-dialect changes. The new test exercises the full ORM construction path via ometa_to_sqa_orm and asserts both the positive outcome and the regression guard against UndeterminedType. No existing mappings are touched or removed.
No files require special attention.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A["Column with dataType MONEY or BIT"] --> B["map_types() in CommonMapTypes"] B --> C{"dataType in _TYPE_MAP?"} C -- "Before fix: NO" --> D["return_custom_type() → UndeterminedType"] D --> E["NOT_COMPUTE set → profiling skipped"] D --> F["sample data = 'OPENMETADATA_UNDETERMIND[value]'"] C -- "After fix: YES" --> G{"dataType match"} G -- "DataType.MONEY" --> H["sqlalchemy.NUMERIC → numeric metrics computed"] G -- "DataType.BIT" --> I["sqlalchemy.BOOLEAN → boolean profiling"]%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%% flowchart TD A["Column with dataType MONEY or BIT"] --> B["map_types() in CommonMapTypes"] B --> C{"dataType in _TYPE_MAP?"} C -- "Before fix: NO" --> D["return_custom_type() → UndeterminedType"] D --> E["NOT_COMPUTE set → profiling skipped"] D --> F["sample data = 'OPENMETADATA_UNDETERMIND[value]'"] C -- "After fix: YES" --> G{"dataType match"} G -- "DataType.MONEY" --> H["sqlalchemy.NUMERIC → numeric metrics computed"] G -- "DataType.BIT" --> I["sqlalchemy.BOOLEAN → boolean profiling"]Reviews (1): Last reviewed commit: "fix(profiler): map MONEY and BIT columns..." | Re-trigger Greptile