112 lines
3.9 KiB
JavaScript
112 lines
3.9 KiB
JavaScript
import pg from 'pg';
|
|
const { Pool } = pg;
|
|
|
|
const liaraPool = new Pool({
|
|
connectionString: 'postgresql://root:hePGFWh8f5TAEWCBK0V8XtQh@el-capitan.liara.cloud:32727/postgres',
|
|
ssl: false,
|
|
});
|
|
|
|
const vpsPool = new Pool({
|
|
connectionString: 'postgresql://user:d1ph12poyhd1o2pDASd2jp2dnbcba@94.101.186.198:5433/steelforesight',
|
|
ssl: false,
|
|
});
|
|
|
|
async function migrate() {
|
|
console.log('Connecting to Liara and VPS PostgreSQL...');
|
|
|
|
// 1. Get list of user tables in Liara
|
|
const tablesRes = await liaraPool.query(`
|
|
SELECT table_name
|
|
FROM information_schema.tables
|
|
WHERE table_schema = 'public' AND table_type = 'BASE TABLE'
|
|
ORDER BY table_name;
|
|
`);
|
|
|
|
const tables = tablesRes.rows.map(r => r.table_name);
|
|
console.log('Tables to migrate:', tables);
|
|
|
|
// Initialize schema on VPS first (we can read db.js DDL or create tables dynamically)
|
|
// Let's create tables if not exist using information_schema
|
|
for (const table of tables) {
|
|
console.log(`\nProcessing schema for: ${table}`);
|
|
|
|
const colsRes = await liaraPool.query(`
|
|
SELECT column_name, data_type, udt_name, is_nullable, column_default
|
|
FROM information_schema.columns
|
|
WHERE table_schema = 'public' AND table_name = $1
|
|
ORDER BY ordinal_position;
|
|
`, [table]);
|
|
|
|
// Check if table exists on VPS
|
|
const checkTable = await vpsPool.query(`
|
|
SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_name = $1
|
|
`, [table]);
|
|
|
|
if (checkTable.rows.length === 0) {
|
|
// Build CREATE TABLE statement
|
|
const colDefs = colsRes.rows.map(col => {
|
|
let type = col.data_type;
|
|
if (col.data_type === 'USER-DEFINED') type = col.udt_name;
|
|
if (col.column_name === 'id' && (col.data_type === 'integer' || col.data_type === 'bigint') && col.column_default?.includes('nextval')) {
|
|
return `"${col.column_name}" SERIAL PRIMARY KEY`;
|
|
}
|
|
let def = `"${col.column_name}" ${type}`;
|
|
if (col.is_nullable === 'NO') def += ' NOT NULL';
|
|
if (col.column_name === 'id' && col.data_type === 'text') def += ' PRIMARY KEY';
|
|
return def;
|
|
}).join(',\n ');
|
|
|
|
const createSql = `CREATE TABLE IF NOT EXISTS "${table}" (\n ${colDefs}\n);`;
|
|
console.log(`Creating table ${table}...`);
|
|
await vpsPool.query(createSql);
|
|
}
|
|
|
|
// Now copy data
|
|
const rowsRes = await liaraPool.query(`SELECT * FROM "${table}"`);
|
|
console.log(`Copying ${rowsRes.rows.length} rows for ${table}...`);
|
|
|
|
if (rowsRes.rows.length > 0) {
|
|
// Clear existing rows on VPS to avoid duplicates
|
|
await vpsPool.query(`TRUNCATE TABLE "${table}" CASCADE;`);
|
|
|
|
for (const row of rowsRes.rows) {
|
|
const keys = Object.keys(row);
|
|
const values = Object.values(row);
|
|
const placeholders = keys.map((_, i) => `$${i + 1}`).join(', ');
|
|
const colNames = keys.map(k => `"${k}"`).join(', ');
|
|
|
|
const insertSql = `INSERT INTO "${table}" (${colNames}) VALUES (${placeholders}) ON CONFLICT DO NOTHING;`;
|
|
await vpsPool.query(insertSql, values);
|
|
}
|
|
console.log(`✓ Copied ${rowsRes.rows.length} rows to VPS ${table}`);
|
|
}
|
|
}
|
|
|
|
// Update sequences if any
|
|
const seqRes = await vpsPool.query(`
|
|
SELECT sequence_name FROM information_schema.sequences WHERE sequence_schema = 'public';
|
|
`);
|
|
for (const seq of seqRes.rows) {
|
|
const seqName = seq.sequence_name;
|
|
const tabName = seqName.split('_')[0];
|
|
try {
|
|
await vpsPool.query(`SELECT setval('${seqName}', COALESCE((SELECT MAX(id) FROM "${tabName}"), 1), true);`);
|
|
console.log(`Updated sequence: ${seqName}`);
|
|
} catch (e) {
|
|
// ignore
|
|
}
|
|
}
|
|
|
|
console.log('\n========================================');
|
|
console.log('✓ PostgreSQL Migration Complete!');
|
|
console.log('========================================');
|
|
|
|
await liaraPool.end();
|
|
await vpsPool.end();
|
|
}
|
|
|
|
migrate().catch(err => {
|
|
console.error('Migration error:', err);
|
|
process.exit(1);
|
|
});
|