This directory contains legacy-to-target ETL transfer logic.
Both legacy migration drivers are frozen. Do not add new migrations to either:
transfers/transfer.py-- the NM_Aquifer (AMPAPI, SQL Server) driver.transfers/transfer_geothermal.py-- the NM_Wells (geothermal) driver, plus itsnmw_mirror_transfer.py,nmw_sql_dump.py, andexport_nmw_csvs.pysupporting modules.
Their top-level entry points raise DeprecationWarning. They are kept runnable
because the tables they populate (NMA_*, NMW_*) are still read by live API
routes, so backfills and re-runs must remain possible -- but they receive no new
features.
There is no deployed transfer job any more. The repo used to carry a Procfile
(web: python3 -m transfers.transfer) that a Cloud Build trigger
(nma-ocotillo-transfer, us-central1) built with buildpacks on every push; that
trigger and the Procfile are gone. Nothing runs a transfer on its own -- the
drivers are invoked by hand, by an engineer, for a backfill. Do not add a
Procfile or a build trigger back.
Consequently their tests live in tests/transfers/ and do not gate CI
(.github/workflows/tests.yml runs pytest with --ignore=tests/transfers), and
transfers/* is omitted from the coverage total in pyproject.toml. Run them by
hand with uv run pytest tests/transfers.
Still live and not deprecated:
services/scoped_transfer.pyand theoco scoped-transfercommand, which import the individual NM_Aquifer transferers directly.transfers/seed_geothermal.py, a dev/test seeder that generates fake data rather than reading a legacy source.
transfers/transfer.py(deprecated)
transfers/transferer.py: base transfer patternstransfers/util.py: shared parsing/mapping helperstransfers/logger.py: transfer loggingtransfers/metrics.py: metrics capture
For high-volume tables, prefer Core batch inserts:
session.execute(insert(Model), rows)
Avoid ORM-heavy per-row object construction for bulk workloads.
- Logs:
transfers/logs/ - Metrics:
transfers/metrics/
Use the transfer-auditing CLI to compare each source CSV against the current destination Postgres table.
source .venv/bin/activate
set -a; source .env; set +a
oco transfer-resultsoco transfer-results --sample-limit 5
oco transfer-results --summary-path transfers/metrics/transfer_results_summary.md--sample-limit: limits sampled key details retained internally per transfer result.--summary-path: path to the markdown report.
If oco is not on your PATH, use:
python -m cli.cli transfer-results --sample-limit 5Default report file:
transfers/metrics/transfer_results_summary.md
Summary columns:
Source Rows: raw row count in the source CSV.Agreed Rows: rows considered in-scope by transfer rules/toggles.Dest Rows: current row count in destination table/model.Missing Agreed:Agreed Rows - Dest Rows(positive means destination is short vs agreed source rows).