fix(er): strict pandas blocking parser, NaT-safe comparisons, quoted link keys - #356
Open
kevincostner17 wants to merge 1 commit into
Open
kevincostner17 wants to merge 1 commit into
kevincostner17 wants to merge 1 commit into
Conversation
…s missing, quoted link keys - resolve_entities/link_entities(backend="duckdb") no longer reject valid DuckDB blocking SQL (e.g. jaro_winkler_similarity(...) > 0.8). The pandas parser still runs to attribute blocking_rule_ids, but its EntityResolutionError is now caught alongside ValueError/KeyError, so rules it cannot read are skipped for attribution as documented. - The pandas blocking parser is now strict. Predicates are split on AND and on "="/"==" outside quoted identifiers and string literals. Each side must be a column reference (l.col, r."quoted col", col) or lower/upper/trim/left/right/substr over one. OR, <, <=, >, >=, !=, <>, literals and arithmetic now raise EntityResolutionError instead of resolving to missing keys and silently producing zero candidate pairs. Quoted identifiers unescape "" and may contain spaces, "=" or "and". A rule that references a column absent from the frame logs a warning. - _is_missing treats every scalar pandas missing value (NaN, NaT, pd.NA, numpy NaT) as missing, not only None and float NaN. Two NaT values no longer score as full agreement and merge records, and NaT/pd.NA blocking keys no longer form candidate pairs. - fd.link builds its default blocking SQL with double-quoted identifiers (embedded quotes escaped as ""), so keys such as "first name" or "e-mail" work on the DuckDB backend. - link_entities records match_threshold, clerical_review_threshold and scoring in runtime_metadata, as resolve_entities does. The external fd.link report records its thresholds too. build_review_queue therefore sorts linkage queues around the configured midpoint instead of 0.75. Closes #236 Closes #237 Closes #238 Closes #266 Closes #271
Contributor
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
FreshData benchmark report —
|
| fixture | n_rows | n_cols | p50 s | p95 s | peak MB | repair % | false-repair % | preserve % | trust | monotonic | export % |
|---|
Authored-code reduction (Metric 6)
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
Fixes five entity-resolution bugs in
src/freshdata/enterprise/entity_resolution.py.blocking_rule_ids, and_parse_blocking_rulesdidn't catch itsEntityResolutionError. Non-equality DuckDB rules such asjaro_winkler_similarity(l.name, r.name) > 0.8therefore aborted the run. The error is now caught; rules the parser can't read are simply not attributed, as documented. The pandas backend still raises._parse_blockingsplit on the first=, sol.id <= r.idbecame the columnid <, which is missing for every record. The parser is now strict:ANDand on=/==outside quoted identifiers and string literals.l.col,r."quoted col",col) orlower/upper/trim/left/right/substrover one.OR,<,<=,>,>=,!=,<>, literals and arithmetic raiseEntityResolutionError.""._is_missingonly recognisedNoneand float NaN. It now treats every scalar pandas missing value (NaN, NaT,pd.NA, numpy NaT) as missing, in both scoring and blocking keys.fd.link(backend="duckdb")failed on keys containing spaces or hyphens. The default blocking SQL now double-quotes identifiers, escaping"as"".link_entitiesreports omitted thresholds.runtime_metadatanow includesmatch_threshold,clerical_review_thresholdandscoring, asresolve_entitiesdoes. The externalfd.linkreport includes its thresholds too, sobuild_review_queuesorts around the configured midpoint instead of 0.75.Behaviour changes
OR, comparison operators, literals, arithmetic,BETWEEN, parenthesised predicates, and unquoted names containing spaces or hyphens. Quote such names, e.g.l."first name" = r."first name".pd.NAfields no longer count as agreement, so records previously merged on missing datetimes can now split.Tests
tests/test_enterprise_entity_resolution.py:"",=andand_is_missingunit casespd.NAin comparisons and blocking keyslink_entitiesmetadata and review-queue ordertests/test_link.py:first name,e-mail,say "hi"andselect, on both backendspytest.importorskip("duckdb").Verification
ruff check .: all checks passedmypy src/freshdata: no issues in 202 source files-m "not online and not large", Python 3.12: 4298 passed, 6 skipped-m "not online and not large", Python 3.9 / pandas 1.5.3: 4294 passed, 10 skippedmainand passes on this branch, on both interpreters.Closes #236
Closes #237
Closes #238
Closes #266
Closes #271