Golang Database Library Orm Example - Delete

Comparison between popular go libraries and ORM for database access layer.
December 15, 2021

sheets of papers, sharp focus, wide shot, trending on artstation, masterpiece, by greg rutkowski, by ross tran, by fenghua zhong, octane, soft render, oil on canvas, colorful, cinematic, environmental concept art

In this post, we will look at how deleting a single record in a table works for these various libraries and ORMs.

In general, this operation is very simple because we only care about deleting and checking for an error.

In short, we want to achieve

DELETE FROM users where id=$1;

Table of Contents

This is part of a series of blog posts including:

The runnable code is available in the repository https://github.com/gmhafiz/golang-database-library-orm-example


There is no drama here. We simply write an sql query and call ExecContext().

const delete = "DELETE FROM users where id=$1"

func (r *database) Delete(ctx context.Context, userID int64) (sql.Result, error) {
	return r.db.ExecContext(ctx, delete, userID)


Same goes with sqlc. We write sql query up front in our query.sql and run sqlc generate.

-- name: DeleteUser :exec
FROM users
WHERE id = $1;

It generates a DeleteUser() method that wraps am ExecContext() method.

const deleteUser = `-- name: DeleteUser :exec
FROM users
WHERE id = $1

func (q *Queries) DeleteUser(ctx context.Context, id int64) error {
	_, err := q.db.ExecContext(ctx, deleteUser, id)
	return err

We simply call that method

func (r *database) Delete(ctx context.Context, id int64) error {
	return r.db.DeleteUser(ctx, id)


Deleting a record reads like a SQL statement which is, like others so far, pretty simple.

_, err := r.db.Delete("users").
	Where(sq.Eq{"id": id}).


Like last operations, we need to remember chain Error because it is not compulsory.

func (r *repo) Delete(ctx context.Context, userID int64) error {
	return r.db.WithContext(ctx).Delete(&User{}, userID).Error

We pass a &User{} struct which indicated gorm that it is deleting this users table. Gorm magically figure out the name of the table you want using the name of the struct.


In sqlboiler, deleting is opposite to gorm when compared to doing an update operation. Here, sqlboiler deletes a record through query building which means two queries are made. Delete() method must be done on the models.User struct.

func (r *database) Delete(ctx context.Context, userID int64) error {
	u, err := r.Get(ctx, userID)
	if err != nil {
		return fmt.Errorf("error getting user")

	_, err = u.Delete(ctx, r.db)
	if err != nil {
		return fmt.Errorf("error deleting user")

	return nil

By setting boil.SetDebug = true we can see the queries being made:

select * from "users" where "id"=$1
DELETE FROM "users" WHERE "id"=$1


Ent does a single query to delete.

func (r *database) Delete(ctx context.Context, userID int64) error {
	return r.db.User.DeleteOneID(uint(userID)).Exec(ctx)

No drama here. Except for sqlboiler, deleting only needs a single sql query, and Gorm for its many pitfalls.

Next > Golang Database Library ORM Example One To Many