Skip to content

mailing_list example: scheduled OpenAddresses staging loader on GCP Cloud Run #47

Description

@ihistand

Goal

Complete the OpenAddresses story in examples/supabase_bigquery_mailing_list (652bf2f) with a scheduled ingestion path: a Python staging loader deployed on GCP Cloud Run Jobs, fired by Cloud Scheduler, feeding the example's existing type: "import" action.

Architecture (division of labor)

Cloud Scheduler (cron, e.g. weekly)
      │
      ▼
Cloud Run Job: load_openaddresses (Python container)
      │  download region/state from OpenAddresses.io → unzip → normalize filename
      ▼
gs://<staging-bucket>/openaddresses/<region>.csv       ← staging only; NO warehouse credentials
      │
      ▼
sqlanvil import action (location: gs://…, format: csv)  ← already in the example
      │  run on a SQLAnvil Cloud workflow cron (or local `sqlanvil run`)
      ▼
oa_ext.openaddresses_us → stg_addresses → addresses_cache → mailing_list

Key property: the Python job only stages files — it never holds database credentials. The warehouse load + downstream models + assertions run through the normal sqlanvil workflow with run history.

Deliverables

  • examples/supabase_bigquery_mailing_list/loader/load_openaddresses.py (region/state arg, download from OpenAddresses, unzip, upload to GCS), Dockerfile, requirements.txt
  • Deploy runbook in the loader README: gcloud builds submitgcloud run jobs creategcloud scheduler jobs create http (job execution via OIDC), incl. required IAM (storage.objectAdmin on the staging bucket, run.invoker for the scheduler SA)
  • Example README: new "Scheduling the refresh" section — loader cron + SQLAnvil Cloud workflow cron pairing, and the storage: credentials entry for gs:// in .df-credentials.json
  • Switch guidance for import.location from the bundled sample CSV to the staged gs:// URI (Cloud-compatible — hosted runs reject local paths)

Notes

  • Deploy pattern mirrors the existing SQLAnvil Cloud runner (Cloud Run Jobs, image via Cloud Build), so no new platform concepts.
  • Keep the loader minimal: stage the standard 11-column CSV as-is; normalization stays in stg_addresses (SQL), not Python.
  • Adapted from a production BigQuery ingestion plan (staged load, clustered target) — here the sqlanvil import + Postgres composite indexes fill those roles.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions