Enhance model synchronization in sequelize.js by adding logic to clean up duplicate pg_description entries before and after sync attempts. Implement error handling for potential sync failures related to duplicate entries, improving robustness and clarity in foreign key management during model synchronization.
This commit is contained in:
@@ -530,10 +530,95 @@ 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
|
||||
try {
|
||||
const tableName = model.tableName;
|
||||
const schema = model.options?.schema || 'public';
|
||||
await sequelize.query(`
|
||||
DO $$
|
||||
DECLARE
|
||||
table_oid oid;
|
||||
dup_count integer;
|
||||
BEGIN
|
||||
-- Finde die OID der Tabelle
|
||||
SELECT oid INTO table_oid
|
||||
FROM pg_catalog.pg_class c
|
||||
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
||||
WHERE c.relname = $1
|
||||
AND n.nspname = $2;
|
||||
|
||||
IF table_oid IS NOT NULL THEN
|
||||
-- Entferne doppelte pg_description Einträge, behalte nur den ersten
|
||||
DELETE FROM pg_catalog.pg_description d1
|
||||
WHERE d1.objoid = table_oid
|
||||
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
|
||||
);
|
||||
|
||||
GET DIAGNOSTICS dup_count = ROW_COUNT;
|
||||
END IF;
|
||||
END $$;
|
||||
`, {
|
||||
bind: [tableName, schema]
|
||||
});
|
||||
} catch (descError) {
|
||||
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
|
||||
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 {
|
||||
const tableName = model.tableName;
|
||||
const schema = model.options?.schema || 'public';
|
||||
await sequelize.query(`
|
||||
DO $$
|
||||
DECLARE
|
||||
table_oid oid;
|
||||
BEGIN
|
||||
-- Finde die OID der Tabelle
|
||||
SELECT oid INTO table_oid
|
||||
FROM pg_catalog.pg_class c
|
||||
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
||||
WHERE c.relname = $1
|
||||
AND n.nspname = $2;
|
||||
|
||||
IF table_oid IS NOT NULL THEN
|
||||
-- Entferne doppelte pg_description Einträge, behalte nur den ersten
|
||||
DELETE FROM pg_catalog.pg_description d1
|
||||
WHERE d1.objoid = table_oid
|
||||
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
|
||||
);
|
||||
END IF;
|
||||
END $$;
|
||||
`, {
|
||||
bind: [tableName, schema]
|
||||
});
|
||||
// Versuche Sync erneut nach Bereinigung
|
||||
console.log(` 🔄 Retrying sync after cleaning duplicate pg_description entries...`);
|
||||
await model.sync({ alter: true, force: false, constraints: false });
|
||||
} catch (retryError) {
|
||||
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
|
||||
if (syncError.message && syncError.message.includes('REFERENCES')) {
|
||||
else if (syncError.message && syncError.message.includes('REFERENCES')) {
|
||||
console.log(` ⚠️ Sequelize tried to create FK despite constraints: false, removing any created FKs...`);
|
||||
try {
|
||||
const tableName = model.tableName;
|
||||
|
||||
Reference in New Issue
Block a user