Phase 2 of the warehouse->TimescaleDB consolidation. Streams the DuckDB
`features` table per-symbol through a server-side cursor in bounded
`chunk_rows` batches (fetchmany), bulk-upserting each via the store's
ON CONFLICT write path so peak RAM stays bounded for the ~5-10M-row warehouse
(a prior whole-table load OOM'd a 2Gi node). Idempotent (re-run overwrites,
no dupes). Verifies row counts + per-feature (count, round(sum,6)) checksums.
CLI `fxhnt warehouse-migrate-pg`; exits non-zero on verification mismatch.
Zero live impact — only COPIES into Timescale; FXHNT_FEATURE_STORE stays duckdb.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>