From a1b6e6ab596b52ff8d718da42c3ace5f5b584ba4 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Fri, 19 Dec 2025 08:34:04 +0100 Subject: [PATCH] Enhance error handling in sequelize.js for Foreign Key Constraint Errors by adding logging for orphaned records and skipping problematic models during synchronization. Update syncDatabase.js to include cleanup logic for orphaned political_office entries, improving database integrity and user feedback during sync operations. --- backend/utils/sequelize.js | 11 +++++++++++ backend/utils/syncDatabase.js | 18 +++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/backend/utils/sequelize.js b/backend/utils/sequelize.js index d6ee782..b3d941d 100644 --- a/backend/utils/sequelize.js +++ b/backend/utils/sequelize.js @@ -577,6 +577,17 @@ const syncModelsAlways = async (models) => { // Überspringe dieses Model und fahre mit dem nächsten fort continue; } + // Wenn Sequelize einen Foreign Key Constraint Fehler hat, entferne verwaiste Einträge oder überspringe das Model + else if (syncError.name === 'SequelizeForeignKeyConstraintError' || (syncError.message && (syncError.message.includes('FOREIGN KEY') || syncError.message.includes('Fremdschlüssel')))) { + const tableName = model.tableName; + const schema = model.options?.schema || 'public'; + console.error(` ❌ Cannot sync ${model.name} (${schema}.${tableName}) due to Foreign Key Constraint Error`); + console.error(` ❌ Detail: ${syncError.parent?.detail || syncError.message}`); + console.error(` ⚠️ This usually means there are orphaned records. Cleanup should have removed them.`); + console.error(` ⚠️ Skipping sync for ${model.name} - please check and fix orphaned records manually`); + // Überspringe dieses Model und fahre mit dem nächsten fort + continue; + } // Wenn Sequelize versucht, Foreign Keys zu erstellen, entferne sie nach dem Fehler else if (syncError.message && syncError.message.includes('REFERENCES')) { console.log(` ⚠️ Sequelize tried to create FK despite constraints: false, removing any created FKs...`); diff --git a/backend/utils/syncDatabase.js b/backend/utils/syncDatabase.js index 54f4dba..f55991f 100644 --- a/backend/utils/syncDatabase.js +++ b/backend/utils/syncDatabase.js @@ -379,7 +379,23 @@ const syncDatabaseForDeployment = async () => { console.log(`✅ ${deletedCount7} verwaiste child_relation Einträge entfernt`); } - if (deletedCount1 === 0 && deletedCount2 === 0 && deletedCount3 === 0 && deletedCount4 === 0 && deletedCount5 === 0 && deletedCount6 === 0 && deletedCount7 === 0) { + // Cleanup political_office mit ungültigen character_id, office_type_id oder region_id + const result8 = await sequelize.query(` + DELETE FROM falukant_data.political_office + WHERE character_id NOT IN ( + SELECT id FROM falukant_data.character + ) OR office_type_id NOT IN ( + SELECT id FROM falukant_type.political_office_type + ) OR region_id NOT IN ( + SELECT id FROM falukant_data.region + ); + `); + const deletedCount8 = result8[1] || 0; + if (deletedCount8 > 0) { + console.log(`✅ ${deletedCount8} verwaiste political_office Einträge entfernt`); + } + + if (deletedCount1 === 0 && deletedCount2 === 0 && deletedCount3 === 0 && deletedCount4 === 0 && deletedCount5 === 0 && deletedCount6 === 0 && deletedCount7 === 0 && deletedCount8 === 0) { console.log("✅ Keine verwaisten Einträge gefunden"); } } catch (e) {