Skip to main content
Glama
migrate-json-to-db.ts3.77 kB
/** * Migrate JSON Data to PostgreSQL * * This script migrates historical quotes from JSON files to PostgreSQL. * Run: npm run db:migrate */ import * as fs from 'fs'; import * as path from 'path'; import { PostgresStorageService } from '../src/database/postgres'; import { HistoricalQuote } from '../src/types'; import { embeddingService } from '../src/services/embedding'; async function migrateData() { console.log('🔄 Starting data migration from JSON to PostgreSQL...\n'); const storage = PostgresStorageService.getInstance(); try { // Check database connection console.log('1️⃣ Checking database connection...'); const isHealthy = await storage.healthCheck(); if (!isHealthy) { throw new Error('Database connection failed'); } console.log('✓ Database connected\n'); // Read JSON files console.log('2️⃣ Reading JSON files...'); const quotesPath = path.join(__dirname, '../data/quotes.json'); if (!fs.existsSync(quotesPath)) { console.log('⚠ No quotes.json found. Creating empty database.'); return; } const quotesData = JSON.parse(fs.readFileSync(quotesPath, 'utf-8')); const quotes: HistoricalQuote[] = quotesData.historicalQuotes || []; console.log(`✓ Found ${quotes.length} historical quotes\n'); // Migrate quotes console.log('3️⃣ Migrating quotes to PostgreSQL...'); let migratedCount = 0; let skippedCount = 0; let errorCount = 0; for (const quote of quotes) { try { // Check if quote already exists const existing = await storage.getQuoteById(quote.id); if (existing) { console.log(` ⊘ Skipping ${quote.id} (already exists)`); skippedCount++; continue; } // Add quote await storage.addQuote(quote); console.log(` ✓ Migrated ${quote.id} - ${quote.customerName}`); migratedCount++; // Generate and store embedding if OpenAI is enabled if (embeddingService.isEnabled()) { try { const rfpText = embeddingService.createRfpText({ rawText: quote.rawRfp, material: quote.normalized.material, processes: quote.normalized.processes, qty: quote.normalized.qtyRange?.[0], tolerances: quote.normalized.tolerances, finish: quote.normalized.finish, notes: quote.notes }); const embedding = await embeddingService.generateEmbedding(rfpText); await storage.updateQuoteEmbedding(quote.id, embedding); console.log(` ↳ Generated embedding for ${quote.id}`); } catch (embError: any) { console.log(` ⚠ Failed to generate embedding: ${embError.message}`); } } } catch (error: any) { console.error(` ✗ Error migrating ${quote.id}: ${error.message}`); errorCount++; } } console.log('\n4️⃣ Migration Summary:'); console.log(` ✓ Migrated: ${migratedCount} quotes`); console.log(` ⊘ Skipped: ${skippedCount} quotes (already existed)`); console.log(` ✗ Errors: ${errorCount} quotes`); if (migratedCount > 0) { console.log('\n✅ Migration completed successfully!'); console.log('💡 Tip: Original JSON files are preserved as backup'); } else if (skippedCount > 0) { console.log('\n✅ All quotes already exist in database'); } } catch (error: any) { console.error('\n❌ Migration failed:', error.message); process.exit(1); } finally { await storage.disconnect(); } } // Run migration migrateData().catch(error => { console.error('Fatal error:', error); process.exit(1); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/r-long/mcp-quoting-system'

If you have feedback or need assistance with the MCP directory API, please join our Discord server