Files
relspecgo/pkg/writers/drizzle
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-28 10:34:20 +02:00
2025-12-28 10:15:30 +02:00
2025-12-28 10:15:30 +02:00

Drizzle Writer

Generates TypeScript/JavaScript files with Drizzle ORM schema definitions from database schema information.

Overview

The Drizzle Writer converts RelSpec's internal database model representation into TypeScript source code with Drizzle ORM schema definitions, including tables, columns, relationships, and constraints.

Features

  • Generates Drizzle-compatible TypeScript schema
  • Supports PostgreSQL and MySQL schemas
  • Creates table definitions with proper column types
  • Generates relationship definitions
  • Handles constraints and indexes
  • Outputs formatted TypeScript code

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/drizzle"
)

func main() {
    options := &writers.WriterOptions{
        OutputPath: "schema.ts",
        Metadata: map[string]interface{}{
            "database_type": "postgresql", // or "mysql"
        },
    }

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

CLI Examples

# Generate Drizzle schema from PostgreSQL database
relspec --input pgsql \
  --conn "postgres://localhost/mydb" \
  --output drizzle \
  --out-file schema.ts

# Convert GORM models to Drizzle
relspec --input gorm --in-file models.go --output drizzle --out-file schema.ts

# Convert JSON schema to Drizzle
relspec --input json --in-file schema.json --output drizzle --out-file db/schema.ts

Generated Code Example

import { pgTable, serial, varchar, text, timestamp, integer } from 'drizzle-orm/pg-core';
import { relations } from 'drizzle-orm';

export const users = pgTable('users', {
  id: serial('id').primaryKey(),
  username: varchar('username', { length: 50 }).notNull().unique(),
  email: varchar('email', { length: 100 }).notNull(),
  bio: text('bio'),
  createdAt: timestamp('created_at').notNull().defaultNow(),
});

export const posts = pgTable('posts', {
  id: serial('id').primaryKey(),
  userId: integer('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
  title: varchar('title', { length: 200 }).notNull(),
  content: text('content'),
});

export const usersRelations = relations(users, ({ many }) => ({
  posts: many(posts),
}));

export const postsRelations = relations(posts, ({ one }) => ({
  user: one(users, {
    fields: [posts.userId],
    references: [users.id],
  }),
}));

Supported Column Types

PostgreSQL

  • serial, bigserial - Auto-increment integers
  • integer, bigint, smallint - Integer types
  • varchar, text - String types
  • boolean - Boolean
  • timestamp, date, time - Date/time types
  • json, jsonb - JSON types
  • uuid - UUID type

MySQL

  • int, bigint, smallint - Integer types
  • varchar, text - String types
  • boolean - Boolean
  • datetime, timestamp - Date/time types
  • json - JSON type

Notes

  • Table names and column names are preserved as-is
  • Relationships are generated as separate relation definitions
  • Constraint actions (CASCADE, etc.) are included in references
  • Schema names other than 'public' are supported
  • Output is formatted TypeScript code