Skip to content

fix(mapping): preserve excluded_attributes on update, backfill relationship source/target class - #152

Open
jeremiaspf wants to merge 1 commit into
databrickslabs:developfrom
jeremiaspf:fix/mapping-backend-excluded-attributes-and-class-resolution
Open

fix(mapping): preserve excluded_attributes on update, backfill relationship source/target class#152
jeremiaspf wants to merge 1 commit into
databrickslabs:developfrom
jeremiaspf:fix/mapping-backend-excluded-attributes-and-class-resolution

Conversation

@jeremiaspf

Copy link
Copy Markdown

What

Companion backend fix to #150 (the Manual Mapping save-state PR), in src/back/objects/mapping/Mapping.py:

  • When updating an existing entity or relationship mapping, if the incoming payload omits excluded_attributes but the previous mapping had one, that list is now carried forward. Previously only the general excluded flag was preserved this way, not the concrete excluded_attributes list — so re-saving a mapping that had excluded attributes could silently re-include them.
  • When resolving a relationship's source_class/target_class for consistency checks, if those fields are empty — as they always are for relationships saved via Manual Mapping, which never sends them — they're now backfilled from the corresponding ontology property's rdfs:domain/rdfs:range instead of being left empty.

Why

#150 stops new Manual Mapping saves from losing source_class/target_class/excluded_attributes going forward. This PR is the counterpart for mappings that already exist without them (created before #150, or from any other code path that doesn't send those fields) — the consistency check now recovers what it needs from the ontology itself rather than reporting incomplete data for an otherwise-correctly-configured relationship.

A note on how this PR came together

This is a delayed follow-up to #146#150: when we first put those together, Mapping.py had since grown a substantial schema-drift feature on develop that we hadn't checked our change against, so we held it back. We've now verified this patch applies cleanly on top of that feature with no overlap at all — the drift-detection code and this fix touch entirely different methods — so there was nothing to reconcile, just due diligence to do first.

How to test

  1. Create an entity mapping with an excluded attribute, save, then re-save the mapping without explicitly re-sending excluded_attributes (e.g. via a code path that omits it) — the attribute should stay excluded instead of reappearing.
  2. Create a relationship via Manual Mapping (which never sends source_class/target_class), then run the mapping consistency check — source_class/target_class should resolve from the property's domain/range instead of showing empty.

…onship source/target class

When updating an existing entity or relationship mapping, if the incoming
payload omits excluded_attributes but the previous mapping had one, that
list is now carried forward — previously only the general excluded flag
was preserved, not the concrete list, so re-saving a mapping that had
excluded attributes could silently re-include them.

When resolving source_class/target_class for a relationship's consistency
checks, if those fields are empty — as they always are for relationships
saved via Manual Mapping, which never sends them — they're now backfilled
from the corresponding ontology property's rdfs:domain/rdfs:range instead
of being left empty. This is the backend counterpart to the companion
Manual Mapping PR, which stops the gap from being created going forward;
this fix handles mappings that already have it.

Verified this applies cleanly on top of develop's schema-drift feature
added to this file since 0.7.1 — the two are unrelated and don't overlap.
@jeremiaspf
jeremiaspf requested a review from a team as a code owner August 22, 2026 09:44
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@benoitcayladbx benoitcayladbx left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relevant as the backend counterpart to #150. On current develop, add_or_update_*_mapping still only preserves the excluded flag, not excluded_attributes, and _diagnose_relationship still reads empty source_class/target_class as-is. Please keep the PR; it needs a tighter contract + tests.

Must fix

  1. Omit vs empty list (correctness). build_entity_mapping / build_relationship_mapping only copy excluded_attributes when data.get("excluded_attributes") is truthy, so an explicit [] (user cleared all exclusions) never lands on new_mapping. Your new branch then treats that as “key absent” and restores the previous list.

    Use key presence, not truthiness:

    if "excluded_attributes" in data:
        new_mapping["excluded_attributes"] = list(data.get("excluded_attributes") or [])
    elif m.get("excluded_attributes"):
        new_mapping["excluded_attributes"] = list(m["excluded_attributes"])

    Mirror the same "excluded_attributes" in data check inside the builders, or preserve only in add_or_update_* and always stamp the list from data when the key is present.

  2. Tests (.cursor/08, src/.coding_rules.md §10). This is domain behaviour — it must have unit tests. Extend tests/units/mapping/test_mapping_service.py (TestAddOrUpdateEntity.test_update_existing) and tests/units/mapping/test_attribute_exclusion.py:

    • update omitting the key keeps the previous excluded_attributes;
    • update sending [] clears them;
    • _diagnose_relationship with empty source_class/target_class fills from property domain/range (and stays empty when the property is unknown).
  3. Changelogchangelogs/v0.8.0/<github-user>_YYYY-MM-DD.log (English).

  4. CLA still pending.

Guidance / nits

  • Diagnostic backfill vs persist. Falling back in _diagnose_relationship unblocks the consistency UI, but the mapping JSON on disk stays empty until something writes source_class. Prefer filling at save time (build_relationship_mapping or Manual Mapping #150) so later consumers (R2RML, agents) see the same data. Diagnosis can keep the fallback for legacy rows.
  • The comment citing EstudioPais -> Pais is fine as an illustration, but a generic “Designer header already shows domain → range” is enough (.cursor/05 — comments explain why, not a tenant-specific example).
  • Reusing ont_prop instead of looking it up twice is good.

Please rebase on latest develop (schema-drift in this file has moved on; your hunks still look isolated, which is good) and add the tests above.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants