diff --git a/internal/database/postgresql.go b/internal/database/postgresql.go index b32acfe..6ecb256 100644 --- a/internal/database/postgresql.go +++ b/internal/database/postgresql.go @@ -349,8 +349,8 @@ func (p *PostgreSQL) BuildRestoreCommand(database, inputFile string, options Res } cmd = append(cmd, "-U", p.cfg.User) - // Parallel jobs - if options.Parallel > 1 { + // Parallel jobs (incompatible with --single-transaction per PostgreSQL docs) + if options.Parallel > 1 && !options.SingleTransaction { cmd = append(cmd, "--jobs="+strconv.Itoa(options.Parallel)) } @@ -371,6 +371,13 @@ func (p *PostgreSQL) BuildRestoreCommand(database, inputFile string, options Res cmd = append(cmd, "--single-transaction") } + // CRITICAL: Exit on first error (by default pg_restore continues on errors) + // This ensures we catch failures immediately instead of at the end + cmd = append(cmd, "--exit-on-error") + + // Skip data restore if table creation fails (prevents duplicate data errors) + cmd = append(cmd, "--no-data-for-failed-tables") + // Add verbose flag for better error reporting cmd = append(cmd, "--verbose") diff --git a/internal/restore/engine.go b/internal/restore/engine.go index 5445c31..33d7d61 100644 --- a/internal/restore/engine.go +++ b/internal/restore/engine.go @@ -865,13 +865,15 @@ func (e *Engine) ensureDatabaseExists(ctx context.Context, dbName string) error } // Database doesn't exist, create it - e.log.Info("Creating database", "name", dbName) + // IMPORTANT: Use template0 to avoid duplicate definition errors from local additions to template1 + // See PostgreSQL docs: https://www.postgresql.org/docs/current/app-pgrestore.html#APP-PGRESTORE-NOTES + e.log.Info("Creating database from template0", "name", dbName) createArgs := []string{ "-p", fmt.Sprintf("%d", e.cfg.Port), "-U", e.cfg.User, "-d", "postgres", - "-c", fmt.Sprintf("CREATE DATABASE \"%s\"", dbName), + "-c", fmt.Sprintf("CREATE DATABASE \"%s\" WITH TEMPLATE template0", dbName), } // Only add -h flag if host is not localhost (to use Unix socket for peer auth) @@ -891,7 +893,7 @@ func (e *Engine) ensureDatabaseExists(ctx context.Context, dbName string) error return fmt.Errorf("failed to create database '%s': %w (output: %s)", dbName, err, strings.TrimSpace(string(output))) } - e.log.Info("Successfully created database", "name", dbName) + e.log.Info("Successfully created database from template0", "name", dbName) return nil }