Code-First ORM For Go: GORM

dak425

Donald Feury

Posted on August 18, 2020

Code-First ORM For Go: GORM

Check out the video for some more elaboration on the topics below.

If you liked it and want to know when I post more videos, be sure to subscribe

Time to start looking at some ORMs for go, today we're gonna start with gorm. Gorm is a code first ORM, meaning we can use go code to define our database scheme, run the migrations, and also interact with the database with the same code.

Connect to the Database

In order to connect to a database using gorm, we simply use the following:

db, err := gorm.Open("sqlite3", "test.db")
if err != nil {
  // Handle error
}
defer db.Close()
Enter fullscreen mode Exit fullscreen mode

We are opening a sqlite3 file, because I didn't want to fiddle with something like MySQL for this.

We handle an error if one occurred, and defer a call to db.Close() to ensure the connection is cleaned up afterwards

Defining Schema with Structs

We have the following structs:

type Channel struct {
    gorm.Model
    Name        string
    Description string
}

type User struct {
    gorm.Model
    Email    string
    Username string
}

type Message struct {
    gorm.Model
    Content   string
    UserID    uint
    ChannelID uint
    User      User
    Channel   Channel
}
Enter fullscreen mode Exit fullscreen mode

Each of these structs will have a corresponding table in our database, with the same columns as the structs have properties.

The gorm.Model struct has some standard properties commonly used in SQL database, check out the docs to see more about it.

You'll notice the Message struct has properties that reference other structs. These are used to map the table relations, read more about how gorm does relationship mapping here.

Migrations

The easiest way to sync up our schema to our structs it to use the AutoMigration method defined on the db instance:

db.AutoMigrate(&Channel{}, &User{}, &Message{})
Enter fullscreen mode Exit fullscreen mode

We pass in an instance of each struct and gorm does some reflection under the hood to make any schema changes, generate the queries, and run them.

Keep in mind, AutoMigrate will only add missing tables, columns, and indexes. It will not remove unused ones, read why here.

Adding Data

To create a new row in our database, we simply create in instance of one of our structs, set the values on its properties, and pass it to the Create method on our database connection:

channel := Channel{Name: "General", Description: "General banter"}

db.Create(&channel)
Enter fullscreen mode Exit fullscreen mode

Tada, data has been inserted into our table!

Finding Data

If you want to grab something from the database, the docs has alot of examples but some notable ones are as follows:

// give me all the channels and unmarshal them into my variable channels, which is of type []Channel
db.Find(&channels)

// give me the first record by primary key, in the channels table and unmarshal it into my variable channel, which is of type Channel
db.First(&channel)

// same as db.First() but gets the last record by primary key
db.Last(&channel)
Enter fullscreen mode Exit fullscreen mode

You can also build where clauses using the Where method:

// Adds a 'where name = "General"' clause to the select query
db.Where("Name = ?", "General").Find(&channels)

// You can pass in structs to act as the where clause source.
// Here it will take the field 'Name' from our channel struct and add it into the where clause
db.Where(&Channel{Name: "General"}).First(&channel)
Enter fullscreen mode Exit fullscreen mode

Error Handling

Gorm handles errors in a way that is a little different than idiomatic go.

After you run a gorm query, it will set a value to the Error variable in the gorm package, if an error occurred while running the query.

Here is an example of checking if the method ended up returning an error:

if err := db.Where("Name = ?", "MissingName").First(&channel).Error; err != nil {
  // Handle error
}
Enter fullscreen mode Exit fullscreen mode

Summary

Gorm makes it fairly easy to manage your database schema and acts as an abstraction over your database backend.

Thank you for reading

💖 💪 🙅 🚩
dak425
Donald Feury

Posted on August 18, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Code-First ORM For Go: GORM
go Code-First ORM For Go: GORM

August 18, 2020