Bun vs GORM
1
Migrator
2
ORM
3
Choose winner
4
Let's GO
# MIGRATOR
Migrator
-
Configure migrations schema
-
Apply all unapplied migrations
-
Write plain SQL in migrations
🍩 Bun
migrator := migrate.NewMigrator(db, migrations.Migrations,
migrate.WithTableName("bar.migrations"),
migrate.WithLocksTableName("bar.migration_locks"),
)
# MIGRATOR
⭐️ GORM
// option 1
if err := db.AutoMigrate(&Article{}); err != nil {
log.Fatal(err)
}
// option 2
if !db.Migrator().HasTable("articles") {
db.Migrator().CreateTable(&Article{})
}
# MIGRATOR
⭐️ GORM
SELECT count(*) FROM information_schema.tables WHERE table_schema = CURRENT_SCHEMA() AND table_name = 'articles' AND table_type = 'BASE TABLE'
SELECT CURRENT_DATABASE()
SELECT c.column_name, c.is_nullable = 'YES', c.udt_name, c.character_maximum_length, c.numeric_precision, c.numeric_precision_radix, c.numeric_scale, c.datetime_precision, 8 * typlen, c.column_default, pd.description, c.identity_increment FROM information_schema.columns AS c JOIN pg_type AS pgt ON c.udt_name = pgt.typname LEFT JOIN pg_catalog.pg_description as pd ON pd.objsubid = c.ordinal_position AND pd.objoid = (SELECT oid FROM pg_catalog.pg_class WHERE relname = c.table_name AND relnamespace = (SELECT oid FROM pg_catalog.pg_namespace WHERE nspname = c.table_schema)) where table_catalog = 'poc' AND table_schema = CURRENT_SCHEMA() AND table_name = 'articles'
SELECT constraint_name FROM information_schema.table_constraints tc JOIN information_schema.constraint_column_usage AS ccu USING (constraint_schema, constraint_name) JOIN information_schema.columns AS c ON c.table_schema = tc.constraint_schema AND tc.table_name = c.table_name AND ccu.column_name = c.column_name WHERE constraint_type IN ('PRIMARY KEY', 'UNIQUE') AND c.table_catalog = 'poc' AND c.table_schema = CURRENT_SCHEMA() AND c.table_name = 'articles' AND constraint_type = 'UNIQUE'
SELECT c.column_name, constraint_name, constraint_type FROM information_schema.table_constraints tc JOIN information_schema.constraint_column_usage AS ccu USING (constraint_schema, constraint_name) JOIN information_schema.columns AS c ON c.table_schema = tc.constraint_schema AND tc.table_name = c.table_name AND ccu.column_name = c.column_name WHERE constraint_type IN ('PRIMARY KEY', 'UNIQUE') AND c.table_catalog = 'poc' AND c.table_schema = CURRENT_SCHEMA() AND c.table_name = 'articles'
SELECT a.attname as column_name, format_type(a.atttypid, a.atttypmod) AS data_type
FROM pg_attribute a JOIN pg_class b ON a.attrelid = b.oid AND relnamespace = (SELECT oid FROM pg_catalog.pg_namespace WHERE nspname = CURRENT_SCHEMA())
WHERE a.attnum > 0 -- hide internal columns
AND NOT a.attisdropped -- hide deleted columns
AND b.relname = 'articles'
SELECT description FROM pg_catalog.pg_description WHERE objsubid = (SELECT ordinal_position FROM information_schema.columns WHERE table_schema = CURRENT_SCHEMA() AND table_name = 'articles' AND column_name = 'id') AND objoid = (SELECT oid FROM pg_catalog.pg_class WHERE relname = 'articles' AND relnamespace = (SELECT oid FROM pg_catalog.pg_namespace WHERE nspname = CURRENT_SCHEMA()))
SELECT description FROM pg_catalog.pg_description WHERE objsubid = (SELECT ordinal_position FROM information_schema.columns WHERE table_schema = CURRENT_SCHEMA() AND table_name = 'articles' AND column_name = 'name') AND objoid = (SELECT oid FROM pg_catalog.pg_class WHERE relname = 'articles' AND relnamespace = (SELECT oid FROM pg_catalog.pg_namespace WHERE nspname = CURRENT_SCHEMA()))
-- ...
# MIGRATOR
ORM
-
Read...
-
Save...
...aggregates using repository
# ORM
🍩 Bun: read
# ORM
Supported 🎉
🍩 Bun: save
Not supported
# ORM
⭐️ GORM: read
# ORM
Supported 🎉
⭐️ GORM: save
Supported, but...
# ORM
⭐️ GORM
a := &Article{}
db.Model(a).Preload("Comments").First(a)
a.Name = "Upd"
db.Save(a)
INSERT INTO "comments" ("article_id","body","id")
VALUES (1,'Bar',2),(1,'Foo',1)
ON CONFLICT ("id") DO UPDATE SET "article_id"="excluded"."article_id" RETURNING "id"
UPDATE "articles" SET "name"='Upd' WHERE "id" = 1
# ORM
⭐️ GORM
a := &Article{}
db.Model(a).Preload("Comments").First(a)
// remove last comment
a.Comments = a.Comments[:2]
db.Save(a)
INSERT INTO "comments" ("article_id","body","id")
VALUES (1,'Baz',3),(1,'Bar',2)
ON CONFLICT ("id") DO UPDATE SET "article_id"="excluded"."article_id" RETURNING "id"
UPDATE "articles" SET "name"='Upd' WHERE "id" = 1
# ORM
⭐️ GORM
db.Model(&a).Association("Comments").Replace(&Comment{
Id: 4,
Body: "Replaced",
})
INSERT INTO "comments" ("article_id","body","id")
VALUES (1,'Replaced',4)
ON CONFLICT ("id") DO UPDATE SET "article_id"="excluded"."article_id" RETURNING "id"
UPDATE "comments" SET "article_id"=NULL
WHERE "comments"."id" <> 4 AND "comments"."article_id" = 1
# ORM
# ADVANTAGES
🍩 Bun advantages
-
One of the most popular ORMs
-
Already integrated in DWH module
-
go-pg migration doc
-
Fixtures support
-
Fast response from maintainers
Bun vs GORM
By Volodymyr Kupriienko
Bun vs GORM
- 386