Files
relspecgo/pkg/writers/pgsql
warkanum 3b88c386a1 fix(codegen): sort map iteration to make generated output deterministic
Table.Columns/Constraints/Indexes/Relationships are Go maps, and every
writer, reader, diff, inspector, and merge code path that iterated them
directly was subject to Go's randomized map order, so identical input
could produce different output (or a different in-report violation/diff
order) on every run. Most visibly this showed up as bun/gorm `unique:`
struct tags changing order across consecutive `make models` runs with no
source change.

Fixed by sorting map iteration (by Sequence then Name, or alphabetically
for string-keyed maps) everywhere the order affects generated output or
first-match tie-break logic, across the bun, gorm, sqlite, dbml, drawdb,
pgsql, prisma, graphql, typeorm, drizzle, and dctx writers; the dctx,
prisma, and typeorm readers; the shared models.GetPrimaryKey/
GetForeignKeys helpers; pkg/diff, pkg/inspector, and pkg/merge; and the
TUI column/relationship pickers in pkg/ui.
2026-08-10 20:54:40 +02:00
..
2025-12-17 20:44:02 +02:00
2025-12-28 10:34:20 +02:00

PostgreSQL Writer

Generates PostgreSQL DDL (Data Definition Language) SQL scripts from database schema information.

Overview

The PostgreSQL Writer converts RelSpec's internal database model representation into PostgreSQL-compatible SQL DDL scripts, including CREATE TABLE statements, constraints, indexes, views, and sequences.

Features

  • Generates complete PostgreSQL DDL
  • Creates schemas, tables, columns
  • Defines constraints (PK, FK, unique, check)
  • Creates indexes
  • Generates views and sequences
  • Supports migration scripts
  • Includes audit triggers (optional)
  • Handles PostgreSQL-specific data types

Usage

Basic Example

package main

import (
    "git.warky.dev/wdevs/relspecgo/pkg/models"
    "git.warky.dev/wdevs/relspecgo/pkg/writers"
    "git.warky.dev/wdevs/relspecgo/pkg/writers/pgsql"
)

func main() {
    options := &writers.WriterOptions{
        OutputPath: "schema.sql",
    }

    writer := pgsql.NewWriter(options)
    err := writer.WriteDatabase(db)
    if err != nil {
        panic(err)
    }
}

CLI Examples

# Generate PostgreSQL DDL from JSON schema
relspec --input json \
  --in-file schema.json \
  --output pgsql \
  --out-file schema.sql

# Convert GORM models to PostgreSQL DDL
relspec --input gorm \
  --in-file models.go \
  --output pgsql \
  --out-file create_tables.sql

# Export live database schema to SQL
relspec --input pgsql \
  --conn "postgres://localhost/source_db" \
  --output pgsql \
  --out-file backup_schema.sql

Generated SQL Example

-- Schema: public

CREATE SCHEMA IF NOT EXISTS public;

-- Table: public.users

CREATE TABLE IF NOT EXISTS public.users (
    id BIGSERIAL PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL,
    bio TEXT,
    created_at TIMESTAMP NOT NULL DEFAULT NOW()
);

-- Constraints for public.users

ALTER TABLE public.users
    ADD CONSTRAINT uq_users_username UNIQUE (username);

-- Indexes for public.users

CREATE INDEX idx_users_email ON public.users (email);

-- Table: public.posts

CREATE TABLE IF NOT EXISTS public.posts (
    id BIGSERIAL PRIMARY KEY,
    user_id BIGINT NOT NULL,
    title VARCHAR(200) NOT NULL,
    content TEXT,
    created_at TIMESTAMP DEFAULT NOW()
);

-- Foreign Keys for public.posts

ALTER TABLE public.posts
    ADD CONSTRAINT fk_posts_user_id
    FOREIGN KEY (user_id)
    REFERENCES public.users (id)
    ON DELETE CASCADE
    ON UPDATE NO ACTION;

-- Indexes for public.posts

CREATE INDEX idx_posts_user_id ON public.posts (user_id);

Writer Options

Metadata Options

options := &writers.WriterOptions{
    OutputPath: "schema.sql",
    Metadata: map[string]interface{}{
        "include_drop":    true,  // Include DROP statements
        "include_audit":   true,  // Include audit triggers
        "if_not_exists":   true,  // Use IF NOT EXISTS
        "migration_mode":  false, // Generate migration script
    },
}

Features

Full DDL Generation

Generates complete database structure:

  • CREATE SCHEMA statements
  • CREATE TABLE with all columns and types
  • PRIMARY KEY constraints
  • FOREIGN KEY constraints with actions
  • UNIQUE constraints
  • CHECK constraints
  • CREATE INDEX statements
  • CREATE VIEW statements
  • CREATE SEQUENCE statements

Migration Mode

When migration_mode is enabled, generates migration scripts with:

  • Version tracking
  • Up/down migrations
  • Transactional DDL
  • Rollback support

Audit Triggers

When include_audit is enabled, adds:

  • Created/updated timestamp triggers
  • Audit logging functionality
  • Change tracking

PostgreSQL-Specific Features

  • Serial types (SERIAL, BIGSERIAL)
  • Advanced types (UUID, JSONB, ARRAY)
  • Schema-qualified names
  • Constraint actions (CASCADE, RESTRICT, SET NULL)
  • Partial indexes
  • Function-based indexes
  • Check constraints with expressions

Data Types

Supports all PostgreSQL data types:

  • Integer types: SMALLINT, INTEGER, BIGINT, SERIAL, BIGSERIAL
  • Numeric types: NUMERIC, DECIMAL, REAL, DOUBLE PRECISION
  • String types: VARCHAR, CHAR, TEXT
  • Date/Time: DATE, TIME, TIMESTAMP, TIMESTAMPTZ, INTERVAL
  • Boolean: BOOLEAN
  • Binary: BYTEA
  • JSON: JSON, JSONB
  • UUID: UUID
  • Network: INET, CIDR, MACADDR
  • Special: ARRAY, HSTORE

Notes

  • Generated SQL is formatted and readable
  • Comments are preserved from source schema
  • Schema names are fully qualified
  • Default values are properly quoted
  • Constraint names follow PostgreSQL conventions
  • Compatible with PostgreSQL 12+