Skip to content

fix(er): strict pandas blocking parser, NaT-safe comparisons, quoted link keys - #356

Open
kevincostner17 wants to merge 1 commit into
mainfrom
fix/er-blocking-and-link
Open

kevincostner17 wants to merge 1 commit into
mainfrom
fix/er-blocking-and-link

Conversation

@kevincostner17

Copy link
Copy Markdown
Contributor

Summary

Fixes five entity-resolution bugs in src/freshdata/enterprise/entity_resolution.py.

Behaviour changes

  • Stricter pandas blocking: rules that are not pure column equalities now raise instead of returning zero or wrong pairs. That covers 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".
  • Missing values: NaT and pd.NA fields no longer count as agreement, so records previously merged on missing datetimes can now split.

Tests

  • tests/test_enterprise_entity_resolution.py:
    • DuckDB non-equality blocking with correct attribution of the equality rules
    • rejected pandas rules (parametrised)
    • pandas vs DuckDB pair parity for valid equality rules
    • quoted identifiers containing spaces, "", = and and
    • the unknown-column warning
    • _is_missing unit cases
    • NaT and pd.NA in comparisons and blocking keys
    • link_entities metadata and review-queue order
  • tests/test_link.py:
    • exact links on the keys first name, e-mail, say "hi" and select, on both backends
    • multi-key exact and fuzzy links with spaced keys, on both backends
    • thresholds recorded for fuzzy and external links
  • DuckDB tests use pytest.importorskip("duckdb").

Verification

  • ruff check .: all checks passed
  • mypy src/freshdata: no issues in 202 source files
  • pytest -m "not online and not large", Python 3.12: 4298 passed, 6 skipped
  • pytest -m "not online and not large", Python 3.9 / pandas 1.5.3: 4294 passed, 10 skipped
  • Each issue's reproduction fails on main and passes on this branch, on both interpreters.

Closes #236
Closes #237
Closes #238
Closes #266
Closes #271

…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
@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: be1cd457-1b30-449a-a953-937973897343


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

FreshData benchmark report — performance

  • freshdata: ?
  • python: ?
  • platform: ?
fixture n_rows n_cols p50 s p95 s peak MB repair % false-repair % preserve % trust monotonic export %

Authored-code reduction (Metric 6)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment