Skip to content

fix(sync): don't touch url/last_modified on non-datastore resources - #29

Merged
luccasmmg merged 1 commit into
mainfrom
fix/sync-skip-non-datastore-resources
Oct 19, 2026
Merged

luccasmmg merged 1 commit into
mainfrom
fix/sync-skip-non-datastore-resources

Conversation

@luccasmmg

Copy link
Copy Markdown
Member

Problem

UAT report (neso-nextgen-shared#12): calling datastore_create with force: true and only fields on an ingested upload, to update its data dictionary, re-ran the whole ingestion pipeline (about 7 minutes for a 428 MB file).

Cause

After every write, _sync_resource_to_ckan sends a resource_patch with last_modified=now, and on create also url=<dump URL>. CKAN core sets url_changed when either field changes. ckanext-aircan's notify hook reads that as a new upload and submits the DAG. The hook only skips resources with url_type="datastore".

On an upload, the patch also replaces the file URL with the dump URL. CKAN strips upload URLs to their last path segment, so the resource's download link can break.

Fix

  • _sync_resource_to_ckan only writes url and last_modified when url_type == "datastore". For upload and link resources it syncs only schema (and datastore_active on a table drop). If there is nothing to sync, it skips the resource_patch.
  • datastore_create keeps the resource's url_type before data_dict["resource"] is overwritten. The dict-form create always counts as datastore-owned. Upsert and delete pass the url_type they already have.
  • A missing url_type counts as not owned, because CKAN link resources also have an empty url_type.

Behaviour change

Upserts and deletes on upload or link resources no longer update the resource's last_modified ("updated" date), and no longer add a CKAN activity entry when there's no schema change. On those resources, last_modified describes the source file.

Testing

  • Unit and endpoint tests for upload, link and datastore-owned resources. pytest: 542 passed.
  • Tested on the local stack (CKAN + Airflow + this service, BigQuery nhs_dev). Steps: upload a CSV, ingest it, then send a fields-only forced datastore_create.
    • Before: last_modified changed and a new pipeline_ckan_to_bigquery run started 145 ms later.
    • After: url and last_modified were unchanged and no DAG run started. resource.schema and datastore_info both showed the new descriptions, and the 3 rows were kept.
    • A datastore-owned resource (dict-form create) still gets its dump url and last_modified.

After a write, the CKAN sync patched `last_modified` (and `url` on
create) on every resource. On an upload or link resource those describe
the source file, and CKAN flags a change to either as `url_changed`, so
ckanext-aircan re-submitted the resource to the ingestion pipeline.
A fields-only `datastore_create` with `force` (updating the data
dictionary) re-ran a full ingestion and replaced the upload's file URL
with the dump URL.

Only patch `url` / `last_modified` when `url_type == "datastore"`;
otherwise sync the schema alone, or skip the patch when there is
nothing to sync.

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 19, 2026

Copy link
Copy Markdown

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: 54889637-5e37-4304-a3aa-c2ed7ba5c1e6
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@luccasmmg
luccasmmg merged commit 83ac930 into main Oct 19, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant