Fixes for re-running reset scripts
This commit is contained in:
@@ -175,8 +175,8 @@ ORDER BY
|
|||||||
c.name,
|
c.name,
|
||||||
st.vendor;
|
st.vendor;
|
||||||
|
|
||||||
-- Types are created by the reset script
|
-- History and status tables
|
||||||
CREATE TABLE calculate_history (
|
CREATE TABLE IF NOT EXISTS calculate_history (
|
||||||
id BIGSERIAL PRIMARY KEY,
|
id BIGSERIAL PRIMARY KEY,
|
||||||
start_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
start_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
end_time TIMESTAMP NULL,
|
end_time TIMESTAMP NULL,
|
||||||
@@ -193,24 +193,18 @@ CREATE TABLE calculate_history (
|
|||||||
additional_info JSONB
|
additional_info JSONB
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE INDEX idx_status_time ON calculate_history(status, start_time);
|
CREATE TABLE IF NOT EXISTS calculate_status (
|
||||||
|
|
||||||
CREATE TABLE calculate_status (
|
|
||||||
module_name module_name PRIMARY KEY,
|
module_name module_name PRIMARY KEY,
|
||||||
last_calculation_timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
last_calculation_timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE INDEX idx_last_calc ON calculate_status(last_calculation_timestamp);
|
CREATE TABLE IF NOT EXISTS sync_status (
|
||||||
|
|
||||||
CREATE TABLE sync_status (
|
|
||||||
table_name VARCHAR(50) PRIMARY KEY,
|
table_name VARCHAR(50) PRIMARY KEY,
|
||||||
last_sync_timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
last_sync_timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
last_sync_id BIGINT
|
last_sync_id BIGINT
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE INDEX idx_last_sync ON sync_status(last_sync_timestamp);
|
CREATE TABLE IF NOT EXISTS import_history (
|
||||||
|
|
||||||
CREATE TABLE import_history (
|
|
||||||
id BIGSERIAL PRIMARY KEY,
|
id BIGSERIAL PRIMARY KEY,
|
||||||
table_name VARCHAR(50) NOT NULL,
|
table_name VARCHAR(50) NOT NULL,
|
||||||
start_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
start_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
@@ -225,5 +219,7 @@ CREATE TABLE import_history (
|
|||||||
additional_info JSONB
|
additional_info JSONB
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE INDEX idx_table_time ON import_history(table_name, start_time);
|
-- Create all indexes after tables are fully created
|
||||||
CREATE INDEX idx_import_history_status ON import_history(status);
|
CREATE INDEX IF NOT EXISTS idx_last_calc ON calculate_status(last_calculation_timestamp);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_last_sync ON sync_status(last_sync_timestamp);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_table_time ON import_history(table_name, start_time);
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -177,38 +177,62 @@ async function resetDatabase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drop types if they exist
|
// Only drop types if we're not preserving history tables
|
||||||
await client.query('DROP TYPE IF EXISTS calculation_status CASCADE;');
|
const historyTablesExist = await client.query(`
|
||||||
await client.query('DROP TYPE IF EXISTS module_name CASCADE;');
|
SELECT EXISTS (
|
||||||
|
SELECT FROM pg_tables
|
||||||
|
WHERE schemaname = 'public'
|
||||||
|
AND tablename IN ('calculate_history', 'import_history')
|
||||||
|
);
|
||||||
|
`);
|
||||||
|
|
||||||
|
if (!historyTablesExist.rows[0].exists) {
|
||||||
|
await client.query('DROP TYPE IF EXISTS calculation_status CASCADE;');
|
||||||
|
await client.query('DROP TYPE IF EXISTS module_name CASCADE;');
|
||||||
|
}
|
||||||
|
|
||||||
// Re-enable triggers/foreign key checks
|
// Re-enable triggers/foreign key checks
|
||||||
await client.query('SET session_replication_role = \'origin\';');
|
await client.query('SET session_replication_role = \'origin\';');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create enum types
|
// Create enum types if they don't exist
|
||||||
outputProgress({
|
outputProgress({
|
||||||
operation: 'Creating enum types',
|
operation: 'Creating enum types',
|
||||||
message: 'Setting up required enum types...'
|
message: 'Setting up required enum types...'
|
||||||
});
|
});
|
||||||
|
|
||||||
await client.query(`
|
// Check if types exist before creating
|
||||||
CREATE TYPE calculation_status AS ENUM ('running', 'completed', 'failed', 'cancelled')
|
const typesExist = await client.query(`
|
||||||
|
SELECT EXISTS (
|
||||||
|
SELECT 1 FROM pg_type
|
||||||
|
WHERE typname = 'calculation_status'
|
||||||
|
) as calc_status_exists,
|
||||||
|
EXISTS (
|
||||||
|
SELECT 1 FROM pg_type
|
||||||
|
WHERE typname = 'module_name'
|
||||||
|
) as module_name_exists;
|
||||||
`);
|
`);
|
||||||
|
|
||||||
await client.query(`
|
if (!typesExist.rows[0].calc_status_exists) {
|
||||||
CREATE TYPE module_name AS ENUM (
|
await client.query(`CREATE TYPE calculation_status AS ENUM ('running', 'completed', 'failed', 'cancelled')`);
|
||||||
'product_metrics',
|
}
|
||||||
'time_aggregates',
|
|
||||||
'financial_metrics',
|
|
||||||
'vendor_metrics',
|
|
||||||
'category_metrics',
|
|
||||||
'brand_metrics',
|
|
||||||
'sales_forecasts',
|
|
||||||
'abc_classification'
|
|
||||||
)
|
|
||||||
`);
|
|
||||||
|
|
||||||
// Read and execute main schema (core tables)
|
if (!typesExist.rows[0].module_name_exists) {
|
||||||
|
await client.query(`
|
||||||
|
CREATE TYPE module_name AS ENUM (
|
||||||
|
'product_metrics',
|
||||||
|
'time_aggregates',
|
||||||
|
'financial_metrics',
|
||||||
|
'vendor_metrics',
|
||||||
|
'category_metrics',
|
||||||
|
'brand_metrics',
|
||||||
|
'sales_forecasts',
|
||||||
|
'abc_classification'
|
||||||
|
)
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read and execute main schema first (core tables)
|
||||||
outputProgress({
|
outputProgress({
|
||||||
operation: 'Running database setup',
|
operation: 'Running database setup',
|
||||||
message: 'Creating core tables...'
|
message: 'Creating core tables...'
|
||||||
@@ -292,39 +316,12 @@ async function resetDatabase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// List all tables in the database after schema execution
|
// Verify core tables were created
|
||||||
const allTables = await client.query(`
|
const existingTables = (await client.query(`
|
||||||
SELECT
|
SELECT table_name
|
||||||
table_schema,
|
|
||||||
table_name,
|
|
||||||
pg_size_pretty(pg_total_relation_size(quote_ident(table_schema) || '.' || quote_ident(table_name))) as size,
|
|
||||||
pg_relation_size(quote_ident(table_schema) || '.' || quote_ident(table_name)) as raw_size
|
|
||||||
FROM information_schema.tables
|
FROM information_schema.tables
|
||||||
WHERE table_schema = 'public'
|
WHERE table_schema = 'public'
|
||||||
`);
|
`)).rows.map(t => t.table_name);
|
||||||
|
|
||||||
if (allTables.rows.length === 0) {
|
|
||||||
outputProgress({
|
|
||||||
operation: 'Warning',
|
|
||||||
message: 'No tables found in database after schema execution'
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
outputProgress({
|
|
||||||
operation: 'Tables after schema execution',
|
|
||||||
message: {
|
|
||||||
count: allTables.rows.length,
|
|
||||||
tables: allTables.rows.map(t => ({
|
|
||||||
schema: t.table_schema,
|
|
||||||
name: t.table_name,
|
|
||||||
size: t.size,
|
|
||||||
rawSize: t.raw_size
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify core tables were created
|
|
||||||
const existingTables = allTables.rows.map(t => t.table_name);
|
|
||||||
|
|
||||||
outputProgress({
|
outputProgress({
|
||||||
operation: 'Core tables verification',
|
operation: 'Core tables verification',
|
||||||
@@ -349,7 +346,7 @@ async function resetDatabase() {
|
|||||||
message: `Successfully created tables: ${CORE_TABLES.join(', ')}`
|
message: `Successfully created tables: ${CORE_TABLES.join(', ')}`
|
||||||
});
|
});
|
||||||
|
|
||||||
// Read and execute config schema
|
// Now read and execute config schema (since core tables exist)
|
||||||
outputProgress({
|
outputProgress({
|
||||||
operation: 'Running config setup',
|
operation: 'Running config setup',
|
||||||
message: 'Creating configuration tables...'
|
message: 'Creating configuration tables...'
|
||||||
@@ -398,37 +395,6 @@ async function resetDatabase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify config tables were created
|
|
||||||
const configTablesResult = await client.query(`
|
|
||||||
SELECT table_name
|
|
||||||
FROM information_schema.tables
|
|
||||||
WHERE table_schema = 'public'
|
|
||||||
`);
|
|
||||||
const existingConfigTables = configTablesResult.rows.map(t => t.table_name);
|
|
||||||
|
|
||||||
outputProgress({
|
|
||||||
operation: 'Config tables verification',
|
|
||||||
message: {
|
|
||||||
found: existingConfigTables,
|
|
||||||
expected: CONFIG_TABLES
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const missingConfigTables = CONFIG_TABLES.filter(
|
|
||||||
t => !existingConfigTables.includes(t)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (missingConfigTables.length > 0) {
|
|
||||||
throw new Error(
|
|
||||||
`Failed to create config tables: ${missingConfigTables.join(', ')}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
outputProgress({
|
|
||||||
operation: 'Config tables created',
|
|
||||||
message: `Successfully created tables: ${CONFIG_TABLES.join(', ')}`
|
|
||||||
});
|
|
||||||
|
|
||||||
// Read and execute metrics schema (metrics tables)
|
// Read and execute metrics schema (metrics tables)
|
||||||
outputProgress({
|
outputProgress({
|
||||||
operation: 'Running metrics setup',
|
operation: 'Running metrics setup',
|
||||||
|
|||||||
Reference in New Issue
Block a user