287 lines
8.3 KiB
Markdown
287 lines
8.3 KiB
Markdown
# Bun: SQL-first Golang ORM
|
|
|
|
[](https://github.com/uptrace/bun/actions)
|
|
[](https://pkg.go.dev/github.com/uptrace/bun)
|
|
[](https://bun.uptrace.dev/)
|
|
[](https://discord.gg/rWtp5Aj)
|
|
[](https://gurubase.io/g/bun)
|
|
|
|
**Lightweight, SQL-first Golang ORM for PostgreSQL, MySQL, MSSQL, SQLite, and Oracle**
|
|
|
|
Bun is a modern ORM that embraces SQL rather than hiding it. Write complex queries in Go with type
|
|
safety, powerful scanning capabilities, and database-agnostic code that works across multiple SQL
|
|
databases.
|
|
|
|
## ✨ Key Features
|
|
|
|
- **SQL-first approach** - Write elegant, readable queries that feel like SQL
|
|
- **Multi-database support** - PostgreSQL, MySQL/MariaDB, MSSQL, SQLite, and Oracle
|
|
- **Type-safe operations** - Leverage Go's static typing for compile-time safety
|
|
- **Flexible scanning** - Query results into structs, maps, scalars, or slices
|
|
- **Performance optimized** - Built on `database/sql` with minimal overhead
|
|
- **Rich relationships** - Define complex table relationships with struct tags
|
|
- **Production ready** - Migrations, fixtures, soft deletes, and OpenTelemetry support
|
|
|
|
## 🚀 Quick Start
|
|
|
|
```bash
|
|
go get github.com/uptrace/bun
|
|
```
|
|
|
|
### Basic Example
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
|
|
"github.com/uptrace/bun"
|
|
"github.com/uptrace/bun/dialect/sqlitedialect"
|
|
"github.com/uptrace/bun/driver/sqliteshim"
|
|
)
|
|
|
|
func main() {
|
|
ctx := context.Background()
|
|
|
|
// Open database
|
|
sqldb, err := sql.Open(sqliteshim.ShimName, "file::memory:")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// Create Bun instance
|
|
db := bun.NewDB(sqldb, sqlitedialect.New())
|
|
|
|
// Define model
|
|
type User struct {
|
|
ID int64 `bun:",pk,autoincrement"`
|
|
Name string `bun:",notnull"`
|
|
}
|
|
|
|
// Create table
|
|
db.NewCreateTable().Model((*User)(nil)).Exec(ctx)
|
|
|
|
// Insert user
|
|
user := &User{Name: "John Doe"}
|
|
db.NewInsert().Model(user).Exec(ctx)
|
|
|
|
// Query user
|
|
err = db.NewSelect().Model(user).Where("id = ?", user.ID).Scan(ctx)
|
|
fmt.Printf("User: %+v\n", user)
|
|
}
|
|
```
|
|
|
|
## 🎯 Why Choose Bun?
|
|
|
|
### Elegant Complex Queries
|
|
|
|
Write sophisticated queries that remain readable and maintainable:
|
|
|
|
```go
|
|
regionalSales := db.NewSelect().
|
|
ColumnExpr("region").
|
|
ColumnExpr("SUM(amount) AS total_sales").
|
|
TableExpr("orders").
|
|
GroupExpr("region")
|
|
|
|
topRegions := db.NewSelect().
|
|
ColumnExpr("region").
|
|
TableExpr("regional_sales").
|
|
Where("total_sales > (SELECT SUM(total_sales) / 10 FROM regional_sales)")
|
|
|
|
var results []struct {
|
|
Region string `bun:"region"`
|
|
Product string `bun:"product"`
|
|
ProductUnits int `bun:"product_units"`
|
|
ProductSales int `bun:"product_sales"`
|
|
}
|
|
|
|
err := db.NewSelect().
|
|
With("regional_sales", regionalSales).
|
|
With("top_regions", topRegions).
|
|
ColumnExpr("region, product").
|
|
ColumnExpr("SUM(quantity) AS product_units").
|
|
ColumnExpr("SUM(amount) AS product_sales").
|
|
TableExpr("orders").
|
|
Where("region IN (SELECT region FROM top_regions)").
|
|
GroupExpr("region, product").
|
|
Scan(ctx, &results)
|
|
```
|
|
|
|
### Flexible Result Scanning
|
|
|
|
Scan query results into various Go types:
|
|
|
|
```go
|
|
// Into structs
|
|
var users []User
|
|
db.NewSelect().Model(&users).Scan(ctx)
|
|
|
|
// Into maps
|
|
var userMaps []map[string]interface{}
|
|
db.NewSelect().Table("users").Scan(ctx, &userMaps)
|
|
|
|
// Into scalars
|
|
var count int
|
|
db.NewSelect().Table("users").ColumnExpr("COUNT(*)").Scan(ctx, &count)
|
|
|
|
// Into individual variables
|
|
var id int64
|
|
var name string
|
|
db.NewSelect().Table("users").Column("id", "name").Limit(1).Scan(ctx, &id, &name)
|
|
```
|
|
|
|
## 📊 Database Support
|
|
|
|
| Database | Driver | Dialect |
|
|
| ------------- | ------------------------------------------ | --------------------- |
|
|
| PostgreSQL | `github.com/uptrace/bun/driver/pgdriver` | `pgdialect.New()` |
|
|
| MySQL/MariaDB | `github.com/go-sql-driver/mysql` | `mysqldialect.New()` |
|
|
| SQLite | `github.com/uptrace/bun/driver/sqliteshim` | `sqlitedialect.New()` |
|
|
| SQL Server | `github.com/denisenkom/go-mssqldb` | `mssqldialect.New()` |
|
|
| Oracle | `github.com/sijms/go-ora/v2` | `oracledialect.New()` |
|
|
|
|
## 🔧 Advanced Features
|
|
|
|
### Table Relationships
|
|
|
|
Define complex relationships with struct tags:
|
|
|
|
```go
|
|
type User struct {
|
|
ID int64 `bun:",pk,autoincrement"`
|
|
Name string `bun:",notnull"`
|
|
Posts []Post `bun:"rel:has-many,join:id=user_id"`
|
|
Profile Profile `bun:"rel:has-one,join:id=user_id"`
|
|
}
|
|
|
|
type Post struct {
|
|
ID int64 `bun:",pk,autoincrement"`
|
|
Title string
|
|
UserID int64
|
|
User *User `bun:"rel:belongs-to,join:user_id=id"`
|
|
}
|
|
|
|
// Load users with their posts
|
|
var users []User
|
|
err := db.NewSelect().
|
|
Model(&users).
|
|
Relation("Posts").
|
|
Scan(ctx)
|
|
```
|
|
|
|
### Bulk Operations
|
|
|
|
Efficient bulk operations for large datasets:
|
|
|
|
```go
|
|
// Bulk insert
|
|
users := []User{{Name: "John"}, {Name: "Jane"}, {Name: "Bob"}}
|
|
_, err := db.NewInsert().Model(&users).Exec(ctx)
|
|
|
|
// Bulk update with CTE
|
|
_, err = db.NewUpdate().
|
|
Model(&users).
|
|
Set("updated_at = NOW()").
|
|
Where("active = ?", true).
|
|
Exec(ctx)
|
|
|
|
// Bulk delete
|
|
_, err = db.NewDelete().
|
|
Model((*User)(nil)).
|
|
Where("created_at < ?", time.Now().AddDate(-1, 0, 0)).
|
|
Exec(ctx)
|
|
```
|
|
|
|
### Migrations
|
|
|
|
Version your database schema:
|
|
|
|
```go
|
|
import "github.com/uptrace/bun/migrate"
|
|
|
|
migrations := migrate.NewMigrations()
|
|
|
|
migrations.MustRegister(func(ctx context.Context, db *bun.DB) error {
|
|
_, err := db.NewCreateTable().Model((*User)(nil)).Exec(ctx)
|
|
return err
|
|
}, func(ctx context.Context, db *bun.DB) error {
|
|
_, err := db.NewDropTable().Model((*User)(nil)).Exec(ctx)
|
|
return err
|
|
})
|
|
|
|
migrator := migrate.NewMigrator(db, migrations)
|
|
err := migrator.Init(ctx)
|
|
err = migrator.Up(ctx)
|
|
```
|
|
|
|
## 📈 Monitoring & Observability
|
|
|
|
### Debug Queries
|
|
|
|
Enable query logging for development:
|
|
|
|
```go
|
|
import "github.com/uptrace/bun/extra/bundebug"
|
|
|
|
db.AddQueryHook(bundebug.NewQueryHook(
|
|
bundebug.WithVerbose(true),
|
|
))
|
|
```
|
|
|
|
### OpenTelemetry Integration
|
|
|
|
Production-ready observability with distributed tracing:
|
|
|
|
```go
|
|
import "github.com/uptrace/bun/extra/bunotel"
|
|
|
|
db.AddQueryHook(bunotel.NewQueryHook(
|
|
bunotel.WithDBName("myapp"),
|
|
))
|
|
```
|
|
|
|
> **Monitoring made easy**: Bun is brought to you by ⭐
|
|
> [**uptrace/uptrace**](https://github.com/uptrace/uptrace). Uptrace is an open-source APM tool that
|
|
> supports distributed tracing, metrics, and logs. You can use it to monitor applications and set up
|
|
> automatic alerts to receive notifications via email, Slack, Telegram, and others.
|
|
>
|
|
> See [OpenTelemetry example](example/opentelemetry) which demonstrates how you can use Uptrace to
|
|
> monitor Bun.
|
|
|
|
## 📚 Documentation & Resources
|
|
|
|
- **[Getting Started Guide](https://bun.uptrace.dev/guide/golang-orm.html)** - Comprehensive
|
|
tutorial
|
|
- **[API Reference](https://pkg.go.dev/github.com/uptrace/bun)** - Complete package documentation
|
|
- **[Examples](https://github.com/uptrace/bun/tree/master/example)** - Working code samples
|
|
- **[Starter Kit](https://github.com/go-bun/bun-starter-kit)** - Production-ready template
|
|
- **[Community Discussions](https://github.com/uptrace/bun/discussions)** - Get help and share ideas
|
|
|
|
## 🤝 Contributing
|
|
|
|
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details on how to
|
|
get started.
|
|
|
|
**Thanks to all our contributors:**
|
|
|
|
<a href="https://github.com/uptrace/bun/graphs/contributors">
|
|
<img src="https://contributors-img.web.app/image?repo=uptrace/bun" alt="Contributors" />
|
|
</a>
|
|
|
|
## 🔗 Related Projects
|
|
|
|
- **[Golang HTTP router](https://github.com/uptrace/bunrouter)** - Fast and flexible HTTP router
|
|
- **[Golang msgpack](https://github.com/vmihailenco/msgpack)** - High-performance MessagePack
|
|
serialization
|
|
|
|
---
|
|
|
|
<div align="center">
|
|
<strong>Star ⭐ this repo if you find Bun useful!</strong><br>
|
|
<sub>Join our community on <a href="https://discord.gg/rWtp5Aj">Discord</a> • Follow updates on <a href="https://github.com/uptrace/bun">GitHub</a></sub>
|
|
</div>
|