Type-Safe SQL Query Builder for Go. Schema Once, Query Forever.
Extract schema from struct tags, validate fields at init, and build queries with zero reflection on the hot path. Returns *T, not interface{}.
Get Startedimport "github.com/zoobz-io/soy"
type User struct {
ID int64 `db:"id" type:"bigserial primary key"`
Email string `db:"email" type:"text unique not null"`
Name string `db:"name" type:"text"`
Age int `db:"age" type:"int"`
}
// Schema extracted and validated here — once
users, _ := soy.New[User](db, "users", postgres.New())
// Every query after: type-safe, zero reflection, validated fields
user, _ := users.Select().
Where("email", "=", "email_param").
Exec(ctx, map[string]any{"email_param": "alice@example.com"})
// Returns *User, not interface{}
active, _ := users.Query().
Where("age", ">=", "min_age").
OrderBy("name", "asc").
Limit(10).
Exec(ctx, map[string]any{"min_age": 18})
// Returns []*User
updated, _ := users.Modify().
Set("age", "new_age").
Where("id", "=", "user_id").
Exec(ctx, map[string]any{"new_age": 31, "user_id": 42})
// UPDATE requires WHERE — prevents accidentsWhy Soy?
All reflection at init. All validation at init. Everything after that is fast, safe, and typed.
Zero Reflection on Hot Path
Schema extracted once at New(). Query building uses O(1) map lookups. No reflection during execution.
True Generic Returns
Select returns *T, Query returns []*T. The compiler enforces correct types. No runtime casting.
Schema Validation at Init
Field name typos caught immediately at New(), not when the query executes at 3am in production.
Safety by Default
DELETE and UPDATE require explicit WHERE clauses. No accidental full-table operations.
Multi-Database Parity
PostgreSQL, MariaDB, SQLite, SQL Server via pluggable ASTQL providers. Same API, different dialects.
JSON-Serializable Specs
Build queries from config files, LLM output, or API request bodies. Validated against the same schema.
Capabilities
Six fluent builders covering the full SQL surface — all schema-validated, all type-safe.
| Feature | Description | Link |
|---|---|---|
| Select & Query | Single and multi-record retrieval with WHERE, ORDER BY, DISTINCT, GROUP BY, and row locking. | Queries |
| Create & Modify | INSERT with conflict handling and UPDATE with required WHERE. Returns the affected record. | Mutations |
| Aggregates | COUNT, SUM, AVG, MIN, MAX with GROUP BY, HAVING, FILTER, and window functions. | Aggregates |
| Compound Queries | UNION, INTERSECT, EXCEPT for set operations across multiple query builders. | Compound |
| Lifecycle Callbacks | OnScan and OnRecord hooks for post-processing, computed fields, and audit logging. | Lifecycle |
| Vector Search | pgvector semantic search with distance operators, embedding columns, and metadata filtering. | pgvector |
Articles
Browse the full soy documentation.