ratel

package module
v0.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 26, 2026 License: Apache-2.0 Imports: 0 Imported by: 0

README

Ratel

Go Version License CI

Ratel is a type-safe PostgreSQL ORM and code generator for Go. It provides compile-time safety for database operations through generated code, eliminating runtime errors from typos in column names or type mismatches.

Features

  • Type-safe queries — Column names, types, and relations are checked at compile time
  • Code generation — Generate models from SQL schema or protobuf definitions
  • Migration support — Built-in diff tool powered by Atlas
  • Relations — HasMany, BelongsTo, ManyToMany with eager loading
  • pgx integration — Built on top of pgx for optimal PostgreSQL support
  • Protobuf support — Generate database models from protobuf definitions with protoc-gen-ratel

Installation

go install github.com/yaroher/ratel/cmd/ratel@latest
go install github.com/yaroher/ratel/cmd/protoc-gen-ratel@latest

Quick Start

1. Define your models
package models

import (
    "github.com/yaroher/ratel/pkg/ddl"
    "github.com/yaroher/ratel/pkg/schema"
)

type UsersAlias string
func (u UsersAlias) String() string { return string(u) }
const UsersAliasName UsersAlias = "users"

type UsersColumnAlias string
func (u UsersColumnAlias) String() string { return string(u) }

const (
    UsersColumnUserID   UsersColumnAlias = "user_id"
    UsersColumnEmail    UsersColumnAlias = "email"
    UsersColumnFullName UsersColumnAlias = "full_name"
)

type UsersScanner struct {
    UserID   int64
    Email    string
    FullName string
}

// ... implement GetTarget, GetSetter, GetValue methods

var Users = func() UsersTable {
    userIDCol := schema.BigSerialColumn(UsersColumnUserID, ddl.WithPrimaryKey[UsersColumnAlias]())
    emailCol := schema.TextColumn(UsersColumnEmail,
        ddl.WithNotNull[UsersColumnAlias](),
        ddl.WithUnique[UsersColumnAlias](),
    )
    fullNameCol := schema.TextColumn(UsersColumnFullName, ddl.WithNotNull[UsersColumnAlias]())

    return UsersTable{
        Table: schema.NewTable[UsersAlias, UsersColumnAlias, *UsersScanner](
            UsersAliasName,
            func() *UsersScanner { return &UsersScanner{} },
            []*ddl.ColumnDDL[UsersColumnAlias]{
                userIDCol.DDL(),
                emailCol.DDL(),
                fullNameCol.DDL(),
            },
        ),
        UserID:   userIDCol,
        Email:    emailCol,
        FullName: fullNameCol,
    }
}()
2. Generate SQL schema
# Generate schema from Go models
ratel schema -p github.com/yourproject/models --discover -o schema.sql
3. Create migrations
# Generate migration diff from Go models
ratel diff -p github.com/yourproject/models --discover -d migrations -n add_users

# Or from SQL file
ratel diff -s schema.sql -d migrations -n add_users
4. Query your data
import (
    "github.com/yaroher/ratel/pkg/dml"
    "github.com/yaroher/ratel/pkg/exec"
)

// Select with type-safe columns
query := dml.Select(Users.Table).
    Columns(Users.UserID, Users.Email, Users.FullName).
    Where(Users.Email.Eq("user@example.com"))

// Execute query
users, err := exec.Query(ctx, db, query)

// Insert
insert := dml.Insert(Users.Table).
    Set(Users.Email.Set("new@example.com")).
    Set(Users.FullName.Set("John Doe")).
    Returning(Users.UserID)

// Update
update := dml.Update(Users.Table).
    Set(Users.FullName.Set("Jane Doe")).
    Where(Users.UserID.Eq(1))

// Delete
del := dml.Delete(Users.Table).
    Where(Users.UserID.Eq(1))

CLI Commands

ratel schema

Generate SQL schema from Go models package.

ratel schema -p <package> [flags]

Flags:
  -p, --package string   Go package path containing models (required)
  -t, --tables strings   Table variable names (e.g., Users,Products)
  -d, --discover         Auto-discover tables from source files
  -o, --output string    Output SQL schema file (default "schema.sql")
ratel diff

Generate SQL migration diff between current schema and models.

ratel diff [flags]

Flags:
  -s, --sql string       SQL schema file to compare against
  -p, --package string   Go package path containing models
  -t, --tables strings   Table variable names (e.g., Users,Products)
      --discover         Auto-discover tables from source files
  -d, --dir string       Migration directory for output (default "./migrations")
  -n, --name string      Migration name (default "migration")
  -v, --pg_version int   PostgreSQL version (default 18)
ratel generate

Generate Go models from SQL schema.

ratel generate -i <input.sql> -o <output_dir> -p <package_name>

Protobuf Integration

Ratel supports generating database models from protobuf definitions using protoc-gen-ratel.

protoc \
    --plugin=protoc-gen-ratel=./bin/protoc-gen-ratel \
    --go_out=. \
    --go_opt=paths=source_relative \
    --ratel_out=. \
    --ratel_opt=paths=source_relative \
    your_schema.proto

Project Structure

ratel/
├── cmd/
│   ├── ratel/              # CLI tool
│   └── protoc-gen-ratel/   # Protobuf plugin
├── pkg/
│   ├── ddl/                # DDL (CREATE TABLE, etc.)
│   ├── dml/                # DML (SELECT, INSERT, UPDATE, DELETE)
│   ├── exec/               # Query execution
│   ├── schema/             # Table and column definitions
│   └── pgx-ext/            # pgx extensions
├── examples/
│   ├── store/              # Hand-written models example
│   └── proto/              # Protobuf-based example
└── ratelproto/             # Ratel protobuf options

Examples

See the examples directory for complete working examples:

  • store — E-commerce schema with users, orders, products, categories, and tags
  • proto — Same schema defined using protobuf

Requirements

  • Go 1.21+
  • PostgreSQL 14+ (for migrations with testcontainers)
  • Docker (for running migration tests)

License

Apache License 2.0 — see LICENSE for details.

Documentation

The Go Gopher

There is no documentation for this package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL