Improve error handling and logging for duplicate pg_description cleanup in sequelize.js. Update comments for clarity on permission requirements and provide detailed instructions for manual cleanup by database administrators. Enhance user feedback during synchronization attempts to address potential permission issues.

This commit is contained in:
Torsten Schulz (local)
2025-12-19 07:56:07 +01:00
parent 642e215c69
commit 48110e9a6f

View File

@@ -530,7 +530,8 @@ const syncModelsAlways = async (models) => {
console.log(` 🔄 Syncing model ${model.name} with constraints: false`); console.log(` 🔄 Syncing model ${model.name} with constraints: false`);
try { try {
// Bereinige doppelte pg_description Einträge vor dem Sync, um "mehr als eine Zeile" Fehler zu vermeiden // Versuche doppelte pg_description Einträge vor dem Sync zu bereinigen
// Hinweis: Benötigt Superuser-Rechte oder spezielle Berechtigungen
try { try {
const tableName = model.tableName; const tableName = model.tableName;
const schema = model.options?.schema || 'public'; const schema = model.options?.schema || 'public';
@@ -554,19 +555,27 @@ const syncModelsAlways = async (models) => {
) )
`); `);
} catch (descError) { } catch (descError) {
console.warn(` ⚠️ Could not clean up duplicate pg_description entries for ${model.name}:`, descError.message); // Ignoriere Berechtigungsfehler - das ist normal, wenn der Benutzer keine Superuser-Rechte hat
if (descError.message && descError.message.includes('Berechtigung')) {
console.log(` Cannot clean up duplicate pg_description entries (requires superuser privileges): ${model.name}`);
} else {
console.warn(` ⚠️ Could not clean up duplicate pg_description entries for ${model.name}:`, descError.message);
}
} }
await model.sync({ alter: true, force: false, constraints: false }); await model.sync({ alter: true, force: false, constraints: false });
} catch (syncError) { } catch (syncError) {
// Wenn Sequelize einen "mehr als eine Zeile" Fehler hat, bereinige pg_description und versuche erneut // Wenn Sequelize einen "mehr als eine Zeile" Fehler hat, versuche pg_description zu bereinigen
if (syncError.message && (syncError.message.includes('mehr als eine Zeile') || syncError.message.includes('more than one row'))) { if (syncError.message && (syncError.message.includes('mehr als eine Zeile') || syncError.message.includes('more than one row'))) {
console.log(` ⚠️ Sequelize encountered duplicate pg_description entries, cleaning up and retrying...`); console.log(` ⚠️ Sequelize encountered duplicate pg_description entries for ${model.name}`);
console.log(` ⚠️ This requires manual cleanup by a database administrator with superuser privileges.`);
console.log(` ⚠️ SQL to fix (run as superuser):`);
const tableName = model.tableName;
const schema = model.options?.schema || 'public';
console.log(` ⚠️ DELETE FROM pg_catalog.pg_description d1 WHERE d1.objoid IN (SELECT c.oid FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relname = '${tableName}' AND n.nspname = '${schema}') AND EXISTS (SELECT 1 FROM pg_catalog.pg_description d2 WHERE d2.objoid = d1.objoid AND d2.objsubid = d1.objsubid AND d2.ctid < d1.ctid);`);
// Versuche trotzdem zu bereinigen (falls Berechtigung vorhanden)
try { try {
const tableName = model.tableName;
const schema = model.options?.schema || 'public';
// Verwende direkte Parameter-Einsetzung, da DO $$ keine Parameterbindung unterstützt
// Die Parameter sind sicher, da sie von Sequelize-Modell-Eigenschaften kommen
await sequelize.query(` await sequelize.query(`
DELETE FROM pg_catalog.pg_description d1 DELETE FROM pg_catalog.pg_description d1
WHERE d1.objoid IN ( WHERE d1.objoid IN (
@@ -588,12 +597,18 @@ const syncModelsAlways = async (models) => {
console.log(` 🔄 Retrying sync after cleaning duplicate pg_description entries...`); console.log(` 🔄 Retrying sync after cleaning duplicate pg_description entries...`);
await model.sync({ alter: true, force: false, constraints: false }); await model.sync({ alter: true, force: false, constraints: false });
} catch (retryError) { } catch (retryError) {
console.error(` ❌ Retry after pg_description cleanup failed:`, retryError.message); // Wenn Berechtigungsfehler, informiere den Benutzer
// Kombiniere beide Fehler für besseres Debugging if (retryError.message && retryError.message.includes('Berechtigung')) {
const combinedError = new Error(`Sync failed: ${syncError.message}. Retry after pg_description cleanup also failed: ${retryError.message}`); console.error(` ❌ Cannot clean up pg_description entries - requires superuser privileges`);
combinedError.originalError = syncError; console.error(` ❌ Please run the SQL command above as a database superuser, then retry the sync`);
combinedError.retryError = retryError; throw syncError; // Wirf den ursprünglichen Fehler
throw combinedError; } else {
console.error(` ❌ Retry after pg_description cleanup failed:`, retryError.message);
const combinedError = new Error(`Sync failed: ${syncError.message}. Retry after pg_description cleanup also failed: ${retryError.message}`);
combinedError.originalError = syncError;
combinedError.retryError = retryError;
throw combinedError;
}
} }
} }
// Wenn Sequelize versucht, Foreign Keys zu erstellen, entferne sie nach dem Fehler // Wenn Sequelize versucht, Foreign Keys zu erstellen, entferne sie nach dem Fehler