← back to Sister Parish Onboarding
scripts/load_pg.js
82 lines
#!/usr/bin/env node
require('dotenv').config({ path: require('path').join(__dirname,'..','.env') });
const fs = require('fs');
const path = require('path');
const { Client } = require('pg');
const data = JSON.parse(fs.readFileSync(path.join(__dirname,'..','output','normalized.json'),'utf8'));
(async () => {
const c = new Client({ connectionString: process.env.DATABASE_URL });
await c.connect();
await c.query(`
CREATE TABLE IF NOT EXISTS sisterparish_catalog (
sp_product_id BIGINT PRIMARY KEY,
handle TEXT NOT NULL,
title TEXT NOT NULL,
vendor TEXT NOT NULL DEFAULT 'Sister Parish',
product_type TEXT,
tags TEXT[],
body_html TEXT,
source_url TEXT,
primary_image TEXT,
images JSONB,
variants JSONB,
has_sample BOOLEAN,
has_bolt BOOLEAN,
has_image BOOLEAN,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_sp_handle ON sisterparish_catalog(handle);
CREATE INDEX IF NOT EXISTS idx_sp_type ON sisterparish_catalog(product_type);
`);
let inserted = 0, updated = 0;
for (const p of data) {
const r = await c.query(
`INSERT INTO sisterparish_catalog
(sp_product_id, handle, title, vendor, product_type, tags, body_html, source_url, primary_image, images, variants, has_sample, has_bolt, has_image)
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14)
ON CONFLICT (sp_product_id) DO UPDATE SET
title=EXCLUDED.title,
tags=EXCLUDED.tags,
body_html=EXCLUDED.body_html,
primary_image=EXCLUDED.primary_image,
images=EXCLUDED.images,
variants=EXCLUDED.variants,
has_sample=EXCLUDED.has_sample,
has_bolt=EXCLUDED.has_bolt,
has_image=EXCLUDED.has_image,
updated_at=NOW()
RETURNING (xmax = 0) AS inserted`,
[p.sp_product_id, p.handle, p.title, p.vendor, p.product_type, p.tags, p.body_html, p.url, p.primary_image, JSON.stringify(p.images), JSON.stringify(p.variants), p.has_sample, p.has_bolt, p.has_image]
);
if (r.rows[0].inserted) inserted++; else updated++;
}
console.log(`Loaded into dw_unified.sisterparish_catalog: ${inserted} inserted, ${updated} updated`);
const cnt = await c.query('SELECT COUNT(*) FROM sisterparish_catalog');
console.log(`Total rows: ${cnt.rows[0].count}`);
// Summary by price tier
const tiers = await c.query(`
SELECT
CASE
WHEN (variants->0->>'vendor_retail')::numeric < 100 THEN 'A: <$100'
WHEN (variants->0->>'vendor_retail')::numeric < 300 THEN 'B: $100-$299'
WHEN (variants->0->>'vendor_retail')::numeric < 500 THEN 'C: $300-$499'
WHEN (variants->0->>'vendor_retail')::numeric < 700 THEN 'D: $500-$699'
ELSE 'E: $700+'
END AS tier,
COUNT(*) AS n
FROM sisterparish_catalog
GROUP BY 1 ORDER BY 1;
`);
console.log('\nPrice tiers (vendor retail, first variant):');
for (const row of tiers.rows) console.log(` ${row.tier}: ${row.n}`);
await c.end();
})().catch(e=>{ console.error(e); process.exit(1); });