Skip to content
/ norm Public

Powerful, optimized Go ORM and Database Orchestrator built for scalability. Provides one-time setup that automates routing complexity. Supports monolith, fallback replicas, R/W separation, and table-level sharding. Its intelligent engine manages internal routing, without worrying about shard ownership.

License

Notifications You must be signed in to change notification settings

skssmd/norm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

27 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

   _  _   ___   ___  __  __ 
  | \| | / _ \ | _ \|  \/  |  
  | .` || (_) ||   /| |\/| |  
  |_|\_| \___/ |_|_\|_|  |_|  
                              
        .-"""-.
       /   _   \   [ norm: The Scalable Go ORM and Database Orchestrator For Postgres]
      |  (o)_(o)|  
      |   (_)   |   + Automatic Routing
     / \   U   / \  + R/W Separation
    |   \ `-' /   | + Table Sharding    
     \___\___/___/  + Multi-Shard Relations with Integrated Joins and Cascade
   

Norm ORM

Go Version License

Norm is a powerful, flexible ORM for Go that supports multiple database architectures including monolithic, read/write split, and sharded configurations. Built on PostgreSQL with pgx/v5, Norm provides automatic query routing, intelligent join handling, and seamless struct scanning.

Why Norm

Please see the benchmark here

✨ Features

  • πŸš€ Fluent Query Builder - Intuitive, chainable API for all CRUD operations
  • πŸ”„ Multiple Database Modes - Monolithic, Read/Write Split, Sharding
  • πŸ”— Smart JOIN Support - Native, App-Side (skey), and Distributed joins
  • πŸ“¦ Struct Scanning - Automatic mapping of query results to Go structs
  • 🎯 Auto Migrations - Automatic table creation from struct definitions
  • ⚑ Bulk Operations - Efficient bulk inserts with struct support
  • πŸ”‘ Foreign & Soft Keys - Full support for fkey and skey relationships
  • 🌐 Sharding Support - Automatic routing across multiple database shards
  • πŸ“Š Type Safety - Compile-time type checking with struct-based operations

πŸ“¦ Installation

go get github.com/skssmd/norm

πŸš€ Quick Start

1. Define Your Models

package main

import (
    "time"
    "github.com/skssmd/norm"
)

type User struct {
    ID        uint       `norm:"index;notnull;pk;auto"`
    Email     string     `norm:"name:useremail;unique;notnull"`
    Name      string     `norm:"name:fullname;notnull"`
    Username  string     `norm:"name:uname;notnull;unique"`
    Age       *uint      `norm:""`
    CreatedAt time.Time  `norm:"notnull;default:NOW()"`
}

type Order struct {
    ID        uint      `norm:"index;notnull;pk;auto"`
    UserID    uint      `norm:"index;notnull;fkey:users.id;ondelete:cascade"`
    Total     float64   `norm:"notnull"`
    Status    string    `norm:"max:20;default:'pending'"`
    CreatedAt time.Time `norm:"notnull;default:NOW()"`
}

2. Setup Database Connection

func main() {
    // Register primary database
    err := norm.Register("postgres://user:pass@localhost:5432/mydb").Primary()
    if err != nil {
        log.Fatal(err)
    }

    // Register tables
    norm.RegisterTable(User{}, "users")
    norm.RegisterTable(Order{}, "orders")

    // Run auto migrations
    norm.Norm()
}

3. Perform CRUD Operations

ctx := context.Background()

// INSERT
user := User{
    Name:     "Alice Williams",
    Email:    "alice@example.com",
    Username: "alicew",
}
rowsAffected, err := norm.Table(user).Insert().Exec(ctx)

// SELECT with scanning
var users []User
err = norm.Table("users").
    Select().
    Where("created_at > $1", time.Now().AddDate(0, -1, 0)).
    OrderBy("created_at DESC").
    All(ctx, &users)

// UPDATE
rowsAffected, err = norm.Table("users").
    Update("name", "Alice Updated").
    Where("username = $1", "alicew").
    Exec(ctx)

// DELETE
rowsAffected, err = norm.Table("users").
    Delete().
    Where("id = $1", 123).
    Exec(ctx)

4. JOIN Queries with Scanning

type UserOrder struct {
    UserName   string  `norm:"name:fullname"`
    OrderTotal float64 `norm:"name:total"`
    Status     string  `norm:"name:status"`
}

var userOrders []UserOrder

err := norm.Table("users", "id", "orders", "user_id").
    Select("users.fullname", "orders.total", "orders.status").
    Where("users.username = $1", "alice").
    OrderBy("orders.created_at DESC").
    All(ctx, &userOrders)

for _, order := range userOrders {
    fmt.Printf("%s: $%.2f (%s)\n", order.UserName, order.OrderTotal, order.Status)
}

πŸ“š Documentation

🎯 Key Concepts

Database Modes

Norm supports multiple database architectures:

  1. Global Monolith - Single primary database with optional replicas
  2. Read/Write Split - Separate pools for read and write operations
  3. Sharding - Distribute tables across multiple database shards

JOIN Types

Norm automatically selects the optimal join strategy:

  • Native JOIN - Standard SQL JOIN when tables are co-located
  • App-Side JOIN - Application-level join for soft-key (skey) relationships
  • Distributed JOIN - Cross-shard joins handled automatically

Struct Scanning

Map query results directly to Go structs with automatic field mapping:

var user User
err := norm.Table("users").
    Select().
    Where("id = $1", 123).
    First(ctx, &user)

πŸ”§ Advanced Features

Bulk Insert

users := []User{
    {Name: "Alice", Email: "alice@example.com", Username: "alice"},
    {Name: "Bob", Email: "bob@example.com", Username: "bob"},
}

rowsAffected, err := norm.Table("users").
    BulkInsert(users).
    Exec(ctx)

Upsert (ON CONFLICT)

user := User{Name: "John", Email: "john@example.com"}

rowsAffected, err := norm.Table(user).
    Insert().
    OnConflict("email", "update", "name", "updated_at").
    Exec(ctx)

Sharding Setup

// Register shards
norm.Register(dsn1).Shard("shard1").Primary()
norm.Register(dsn2).Shard("shard2").Primary()

// Assign tables to shards
norm.RegisterTable(User{}, "users").Primary("shard1")
norm.RegisterTable(Order{}, "orders").Primary("shard1")
norm.RegisterTable(Analytics{}, "analytics").Standalone("shard2")

πŸ§ͺ Examples

Check out the examples/ directory for complete working examples:

  • Basic CRUD operations
  • JOIN queries with scanning
  • Sharding configurations
  • Bulk operations
  • Migration examples

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • Built with pgx/v5 - High-performance PostgreSQL driver
  • Inspired by modern ORM patterns and best practices

πŸ“ž Support


Made with ❀️ by the Norm team

About

Powerful, optimized Go ORM and Database Orchestrator built for scalability. Provides one-time setup that automates routing complexity. Supports monolith, fallback replicas, R/W separation, and table-level sharding. Its intelligent engine manages internal routing, without worrying about shard ownership.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages