Fx ORM Module
Fx module for orm.
Installation
go get github.com/ankorstore/yokai/fxorm
Documentation
Dependencies
This module is intended to be used alongside:
Loading
To load the module in your Fx application:
package main
import (
"github.com/ankorstore/yokai/fxconfig"
"github.com/ankorstore/yokai/fxlog"
"github.com/ankorstore/yokai/fxorm"
"github.com/ankorstore/yokai/fxtrace"
"go.uber.org/fx"
"gorm.io/gorm"
)
type Model struct {
Name string
}
func main() {
fx.New(
fxconfig.FxConfigModule, // load the module dependencies
fxlog.FxLogModule,
fxtrace.FxTraceModule,
fxorm.FxOrmModule, // load the module
fx.Invoke(func(gormDB *gorm.DB) { // invoke the orm
gormDB.Create(&Model{Name: "some name"})
}),
).Run()
}
Configuration
This module provides the possibility to configure the ORM driver
:
sqlite
for SQLite databases
mysql
for MySQL databases
postgres
for PostgreSQL databases
sqlserver
for SQL Server databases
You can also provide to the ORM the databasedsn
, some config
, and configure SQL queries logging
and tracing
.
# ./configs/config.yaml
app:
name: app
env: dev
version: 0.1.0
debug: false
modules:
orm:
driver: mysql # driver to use
dsn: "user:password@tcp(localhost:3306)/db?parseTime=True" # database DSN to use
config:
dry_run: false # disabled by default
skip_default_transaction: false # disabled by default
full_save_associations: false # disabled by default
prepare_stmt: false # disabled by default
disable_automatic_ping: false # disabled by default
disable_foreign_key_constraint_when_migrating: false # disabled by default
ignore_relationships_when_migrating: false # disabled by default
disable_nested_transaction: false # disabled by default
allow_global_update: false # disabled by default
query_fields: false # disabled by default
translate_error: false # disabled by default
log:
enabled: true # to log SQL queries, disabled by default
level: info # with a minimal level
values: true # by adding or not clear SQL queries parameters values in logs, disabled by default
trace:
enabled: true # to trace SQL queries, disabled by default
values: true # by adding or not clear SQL queries parameters values in trace spans, disabled by default
See GORM Config for more details about the modules.orm.config
configuration keys.
For security reasons, you should avoid to hardcode DSN sensible parts (like the password) in your config files, you can use the env vars placeholders instead:
# ./configs/config.yaml
modules:
orm:
driver: mysql
dsn: "${MYSQL_USER}:${MYSQL_PASSWORD}@tcp(${MYSQL_HOST}:${MYSQL_PORT})/${MYSQL_DATABASE}?parseTime=True"
Auto migrations
This module provides the possibility to run automatically your schemas migrations
with RunFxOrmAutoMigrate()
:
package main
import (
"github.com/ankorstore/yokai/fxconfig"
"github.com/ankorstore/yokai/fxlog"
"github.com/ankorstore/yokai/fxorm"
"github.com/ankorstore/yokai/fxtrace"
"go.uber.org/fx"
"gorm.io/gorm"
)
type Model struct {
Name string
}
func main() {
fx.New(
fxconfig.FxConfigModule, // load the module dependencies
fxlog.FxLogModule,
fxtrace.FxTraceModule,
fxorm.FxOrmModule, // load the module
fxorm.RunFxOrmAutoMigrate(&Model{}), // run auto migration for Model
fx.Invoke(func(gormDB *gorm.DB) { // invoke the orm
gormDB.Create(&Model{Name: "some name"})
}),
).Run()
}
See GORM performance recommendations.
Disable Default Transaction
Gorm performs write (create/update/delete) operations by default inside a transaction to ensure data consistency, which
is not optimized for performance.
You can disable it in the configuration:
# ./configs/config.yaml
modules:
orm:
config:
skip_default_transaction: true # disable default transaction
Cache Prepared Statement
To create a prepared statement when executing any SQL (and cache them to speed up future calls):
# ./configs/config.yaml
modules:
orm:
config:
prepare_stmt: true # enable prepared statements
Override
By default, the gorm.DB
is created by
the DefaultOrmFactory.
If needed, you can provide your own factory and override the module:
package main
import (
"github.com/ankorstore/yokai/fxconfig"
"github.com/ankorstore/yokai/fxlog"
"github.com/ankorstore/yokai/fxorm"
"github.com/ankorstore/yokai/fxtrace"
"github.com/ankorstore/yokai/orm"
"go.uber.org/fx"
"gorm.io/gorm"
)
type CustomOrmFactory struct{}
func NewCustomOrmFactory() orm.OrmFactory {
return &CustomOrmFactory{}
}
func (f *CustomOrmFactory) Create(options ...orm.OrmOption) (*gorm.DB, error) {
return &gorm.DB{...}, nil
}
type Model struct {
Name string
}
func main() {
fx.New(
fxconfig.FxConfigModule, // load the module dependencies
fxlog.FxLogModule,
fxtrace.FxTraceModule,
fxorm.FxOrmModule, // load the module
fx.Decorate(NewCustomOrmFactory), // override the module with a custom factory
fx.Invoke(func(customDb *gorm.DB) { // invoke the custom ORM
customDb.Create(&Model{Name: "custom"})
}),
).Run()
}