diff --git a/cmd/dump/dump.go b/cmd/dump/dump.go
index dbce9052..e43e323e 100644
--- a/cmd/dump/dump.go
+++ b/cmd/dump/dump.go
@@ -12,26 +12,28 @@ import (
)
var (
- host string
- port int
- db string
- user string
- password string
- schema string
- multiFile bool
- file string
+ host string
+ port int
+ db string
+ user string
+ password string
+ schema string
+ multiFile bool
+ file string
+ noComments bool
)
// DumpConfig holds configuration for dump execution
type DumpConfig struct {
- Host string
- Port int
- DB string
- User string
- Password string
- Schema string
- MultiFile bool
- File string
+ Host string
+ Port int
+ DB string
+ User string
+ Password string
+ Schema string
+ MultiFile bool
+ File string
+ NoComments bool
}
var DumpCmd = &cobra.Command{
@@ -52,6 +54,7 @@ func init() {
DumpCmd.Flags().StringVar(&schema, "schema", "public", "Schema name to dump (default: public)")
DumpCmd.Flags().BoolVar(&multiFile, "multi-file", false, "Output schema to multiple files organized by object type")
DumpCmd.Flags().StringVar(&file, "file", "", "Output file path (required when --multi-file is used)")
+ DumpCmd.Flags().BoolVar(&noComments, "no-comments", false, "Do not output object comment headers")
}
// ExecuteDump executes the dump operation with the given configuration
@@ -82,7 +85,7 @@ func ExecuteDump(config *DumpConfig) (string, error) {
diffs := diff.GenerateMigration(emptyIR, schemaIR, config.Schema)
// Create dump formatter
- formatter := dump.NewDumpFormatter(schemaIR.Metadata.DatabaseVersion, config.Schema)
+ formatter := dump.NewDumpFormatter(schemaIR.Metadata.DatabaseVersion, config.Schema, config.NoComments)
if config.MultiFile {
// Multi-file mode - output to files
@@ -109,14 +112,15 @@ func runDump(cmd *cobra.Command, args []string) error {
// Create config from command-line flags
config := &DumpConfig{
- Host: host,
- Port: port,
- DB: db,
- User: user,
- Password: finalPassword,
- Schema: schema,
- MultiFile: multiFile,
- File: file,
+ Host: host,
+ Port: port,
+ DB: db,
+ User: user,
+ Password: finalPassword,
+ Schema: schema,
+ MultiFile: multiFile,
+ File: file,
+ NoComments: noComments,
}
// Execute dump
diff --git a/cmd/dump/dump_test.go b/cmd/dump/dump_test.go
index 28b79da6..3d9a63a0 100644
--- a/cmd/dump/dump_test.go
+++ b/cmd/dump/dump_test.go
@@ -2,9 +2,13 @@ package dump
import (
"os"
+ "strings"
"testing"
"github.com/pgschema/pgschema/cmd/util"
+ "github.com/pgschema/pgschema/internal/diff"
+ "github.com/pgschema/pgschema/internal/dump"
+ "github.com/pgschema/pgschema/ir"
"github.com/spf13/cobra"
)
@@ -288,3 +292,101 @@ func TestDumpCommand_PgpassFile(t *testing.T) {
t.Error("Expected error with unreachable database, but got nil")
}
}
+
+func TestDumpCommand_NoCommentsFlag(t *testing.T) {
+ // Test that the --no-comments flag is defined
+ flags := DumpCmd.Flags()
+ noCommentsFlag := flags.Lookup("no-comments")
+ if noCommentsFlag == nil {
+ t.Error("Expected --no-comments flag to be defined")
+ }
+
+ // Verify default value is false
+ if noCommentsFlag.DefValue != "false" {
+ t.Errorf("Expected --no-comments default to be 'false', got '%s'", noCommentsFlag.DefValue)
+ }
+}
+
+func TestNoComments_SingleFile(t *testing.T) {
+ // Create test diffs
+ diffs := []diff.Diff{
+ {
+ Statements: []diff.SQLStatement{
+ {
+ SQL: "CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT NOT NULL);",
+ CanRunInTransaction: true,
+ },
+ },
+ Type: diff.DiffTypeTable,
+ Operation: diff.DiffOperationCreate,
+ Path: "public.users",
+ Source: &ir.Table{
+ Name: "users",
+ },
+ },
+ {
+ Statements: []diff.SQLStatement{
+ {
+ SQL: "COMMENT ON TABLE users IS 'User accounts';",
+ CanRunInTransaction: true,
+ },
+ },
+ Type: diff.DiffTypeComment,
+ Operation: diff.DiffOperationCreate,
+ Path: "public.users",
+ Source: &ir.Table{
+ Name: "users",
+ },
+ },
+ }
+
+ t.Run("WithComments", func(t *testing.T) {
+ formatter := dump.NewDumpFormatter("PostgreSQL 17.0", "public", false)
+ output := formatter.FormatSingleFile(diffs)
+
+ // Should contain dump header
+ if !strings.Contains(output, "-- pgschema database dump") {
+ t.Error("Expected output to contain dump header")
+ }
+
+ // Should contain object comment header
+ if !strings.Contains(output, "-- Name: users; Type: TABLE") {
+ t.Error("Expected output to contain object comment header")
+ }
+
+ // Should contain DDL
+ if !strings.Contains(output, "CREATE TABLE users") {
+ t.Error("Expected output to contain DDL")
+ }
+
+ // Should contain COMMENT ON statement (this is schema content, not commentary)
+ if !strings.Contains(output, "COMMENT ON TABLE users") {
+ t.Error("Expected output to contain COMMENT ON statement")
+ }
+ })
+
+ t.Run("NoComments", func(t *testing.T) {
+ formatter := dump.NewDumpFormatter("PostgreSQL 17.0", "public", true)
+ output := formatter.FormatSingleFile(diffs)
+
+ // Should still contain dump header (retained per design)
+ if !strings.Contains(output, "-- pgschema database dump") {
+ t.Error("Expected output to contain dump header even with --no-comments")
+ }
+
+ // Should NOT contain object comment header
+ if strings.Contains(output, "-- Name: users; Type: TABLE") {
+ t.Error("Expected output to NOT contain object comment header with --no-comments")
+ }
+
+ // Should still contain DDL
+ if !strings.Contains(output, "CREATE TABLE users") {
+ t.Error("Expected output to contain DDL")
+ }
+
+ // Should still contain COMMENT ON statement (this is schema content)
+ if !strings.Contains(output, "COMMENT ON TABLE users") {
+ t.Error("Expected output to contain COMMENT ON statement")
+ }
+ })
+}
diff --git a/cmd/dump/multifile_test.go b/cmd/dump/multifile_test.go
index 347b8baa..fb9cacd4 100644
--- a/cmd/dump/multifile_test.go
+++ b/cmd/dump/multifile_test.go
@@ -77,7 +77,7 @@ func TestCreateMultiFileOutput(t *testing.T) {
}
// Test the FormatMultiFile function
- formatter := dump.NewDumpFormatter("PostgreSQL 17.0", "public")
+ formatter := dump.NewDumpFormatter("PostgreSQL 17.0", "public", false)
err := formatter.FormatMultiFile(diffs, outputPath)
if err != nil {
t.Fatalf("FormatMultiFile failed: %v", err)
@@ -154,7 +154,7 @@ func TestCreateMultiFileOutput(t *testing.T) {
func TestDumpFormatterHelpers(t *testing.T) {
// Create a formatter instance for testing helper methods
- formatter := dump.NewDumpFormatter("PostgreSQL 17.0", "public")
+ formatter := dump.NewDumpFormatter("PostgreSQL 17.0", "public", false)
// Test getObjectDirectory through the formatter
testObjectDirectories := []struct {
diff --git a/docs/cli/dump.mdx b/docs/cli/dump.mdx
index b610c3ea..ca3c68f4 100644
--- a/docs/cli/dump.mdx
+++ b/docs/cli/dump.mdx
@@ -137,11 +137,17 @@ pgschema apply --host staging-host --db myapp --user postgres --file current.sql
Output file path (required when --multi-file is used)
-
+
For single-file mode, this is optional (defaults to stdout).
For multi-file mode, this specifies the main file path.
+
+ Do not output object comment headers (e.g., `-- Name: users; Type: TABLE; Schema: -; Owner: -`).
+
+ The dump header with pgschema version information is retained. This option is useful when you need pure DDL output without per-object commentary.
+
+
## Ignoring Objects
You can exclude specific database objects from dumps using a `.pgschemaignore` file. See [Ignore (.pgschemaignore)](/cli/ignore) for complete documentation.
diff --git a/internal/dump/formatter.go b/internal/dump/formatter.go
index 00aa8b24..68f3cd6c 100644
--- a/internal/dump/formatter.go
+++ b/internal/dump/formatter.go
@@ -16,13 +16,15 @@ import (
type DumpFormatter struct {
dbVersion string
targetSchema string
+ noComments bool
}
// NewDumpFormatter creates a new DumpFormatter
-func NewDumpFormatter(dbVersion string, targetSchema string) *DumpFormatter {
+func NewDumpFormatter(dbVersion string, targetSchema string, noComments bool) *DumpFormatter {
return &DumpFormatter{
dbVersion: dbVersion,
targetSchema: targetSchema,
+ noComments: noComments,
}
}
@@ -46,8 +48,12 @@ func (f *DumpFormatter) FormatSingleFile(diffs []diff.Diff) string {
output.WriteString("\n")
}
} else {
- // Add object comment header
- output.WriteString(f.formatObjectCommentHeader(step))
+ // Add object comment header (unless --no-comments is set)
+ if !f.noComments {
+ output.WriteString(f.formatObjectCommentHeader(step))
+ } else if i > 0 {
+ output.WriteString("\n") // Add separator between statements
+ }
// Add the SQL statements
for _, stmt := range step.Statements {
@@ -195,8 +201,10 @@ func (f *DumpFormatter) writeObjectFile(filePath string, diffs []diff.Diff) erro
}
}
- // Add object comment header
- file.WriteString(f.formatObjectCommentHeader(step))
+ // Add object comment header (unless --no-comments is set)
+ if !f.noComments {
+ file.WriteString(f.formatObjectCommentHeader(step))
+ }
// Print the SQL statements
for _, stmt := range step.Statements {