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`);
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 {
const tableName = model.tableName;
const schema = model.options?.schema || 'public';
@@ -554,19 +555,27 @@ const syncModelsAlways = async (models) => {
)
`);
} catch (descError) {
// 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 });
} 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'))) {
console.log(` ⚠️ Sequelize encountered duplicate pg_description entries, cleaning up and retrying...`);
try {
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';
// Verwende direkte Parameter-Einsetzung, da DO $$ keine Parameterbindung unterstützt
// Die Parameter sind sicher, da sie von Sequelize-Modell-Eigenschaften kommen
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 {
await sequelize.query(`
DELETE FROM pg_catalog.pg_description d1
WHERE d1.objoid IN (
@@ -588,14 +597,20 @@ const syncModelsAlways = async (models) => {
console.log(` 🔄 Retrying sync after cleaning duplicate pg_description entries...`);
await model.sync({ alter: true, force: false, constraints: false });
} catch (retryError) {
// Wenn Berechtigungsfehler, informiere den Benutzer
if (retryError.message && retryError.message.includes('Berechtigung')) {
console.error(` ❌ Cannot clean up pg_description entries - requires superuser privileges`);
console.error(` ❌ Please run the SQL command above as a database superuser, then retry the sync`);
throw syncError; // Wirf den ursprünglichen Fehler
} else {
console.error(` ❌ Retry after pg_description cleanup failed:`, retryError.message);
// Kombiniere beide Fehler für besseres Debugging
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
else if (syncError.message && syncError.message.includes('REFERENCES')) {
console.log(` ⚠️ Sequelize tried to create FK despite constraints: false, removing any created FKs...`);