Repository navigation
HDXDSYS-3031 Replace list fields such as groups in package_revise instead of merging by position - #130
Merged
Conversation
…ng by position package_revise merges an update list into the existing list by index. The existing elements keep their ids and CKAN resolves groups by id before name, so changed locations were not applied: new groups were only added past the end of the old list and removals were only sent when the removed element was last. Filter out non-resource list keys present in the existing dataset so the update replaces them.
- _revise_filter adds -<key> only when the merged list differs from HDX - _merge_list merges update dicts over matching HDX dicts (by id/name, else position) so unsent fields are kept - keep_crisis_tags only runs when the update has tags, so tags are not wiped when the caller sends none Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- _merge_list matches by id first, then name, and no longer merges dicts without an id or name by position (fields leaked from removed entries) - A null or non-list existing value is treated as an empty list instead of raising TypeError - New _merge_list_fields does the in-place merge and returns the changed keys; _revise_filter only builds the filter - Changed list keys already in keys_to_delete are not added to the filter twice - Add return type and Returns: docstring section to _revise_filter
Add a concurrency group so push and pull_request runs for the same branch don't run test_ckan against the shared hdx_python_api_test dataset at once. Read resource generation fixtures from disk instead of raw.githubusercontent.com, which intermittently returns 501 for empty.csv.
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.
Problem
Updating an existing dataset does not reliably change its locations (groups). Seen on stage with hdx-scraper-ophi:
Cause
_revise_datasetsends the caller's groups as[{"name": ...}, ...]in theupdateofpackage_revise.update_merge_list(dictization_functions.py) merges the update list into the existing list by index, so each existing element keeps itsidand onlynameis overwritten.package_membership_list_save(model_save.py) looks a group up byidbeforename, so every existing position keeps its old group. New groups are only added past the end of the old list._revise_filteronly emitted-groups__Nwhen the removed element was the last one, so other removals never reached CKAN.This matches the stage results exactly: global-mpi had 112 groups, and the only appended element (index 112,
zwe) was already present. The HAPI dataset had 98, and of the appendedton…zweonlyvutwas new.The bug dates from #60 (6.2.2, Feb 2024).
Fix
For each non-resource list key in both the update and the existing dataset,
_merge_list_fields:idornameover the HDX dict with the sameid(or failing that,name), so fields the caller didn't send are kept (_merge_list). A new group has noid, so CKAN looks it up byname.idnorname(eg.customviz) as given. Matching them by position would carry fields over from a removed entry.nullor non-list HDX value as an empty list._revise_filteradds-<key>for each changed key, skipping keys already inkeys_to_delete. CKAN appliesfilterbeforeupdate, so the list is replaced by the merged list.Resources are unchanged and still handled by index via
resources_to_delete.keep_crisis_tagsnow only runs when the update contains tags. Previously it set the update's tags to just the crisis tags (or[]), which with the new filter would wipe a dataset's tags when the caller sent none. When the caller sends tags, crisis tags are still kept becausekeep_crisis_tagsadds them to the update's tags.Effect
-groups/-tags. Pipelines whose location tags have drifted since 2024 will lose stale locations and gain missing ones on their next run.Testing
test_update_logicfilters are unchanged frommain; their expected updates no longer contain"tags": [].test_revise_filter_lists(changed vs unchanged lists, merged ids, unsent fields kept, dicts withoutid/namesent as given,nullHDX value, no duplicate filter withkeys_to_delete) andtest_merge_list_id_before_name.test_ckan, an integration test that needsHDX_PIPELINE_GSHEET_AUTH(unchanged by this PR).customvizwhen omitted from updatedisplacementcustomvizentry removedkeys_to_delete=["groups"]with changed groupsNot covered on stage: keeping
crisis-*tags, andid-before-namematching (unit-tested only).