Golang Update PostgreSQL MySQL

API

To see the full list of supported methods, see API referenceopen in new window.

db.NewUpdate(). With("cte_name", subquery). Model(&strct). Model(&slice). Model(&map). // only map[string]interface{} Column("col1", "col2"). // list of columns to update ExcludeColumn("col1"). // all columns except col1 ExcludeColumn("*"). // exclude all columns Table("table1", "table2"). // quotes table names TableExpr("table1 AS t1"). // arbitrary unsafe expression TableExpr("(?) AS alias", subquery). ModelTableExpr("table1 AS t1"). // overrides model table name Value("col1", "expr1", arg1, arg2). // overrides column value // Generates `SET col1 = 'value1'` Set("col1 = ?", "value1"). SetColumn("col1", "?", "value1"). OmitZero() // don't update struct fields having zero values WherePK(). // where using primary keys Where("id = ?", 123). Where("name LIKE ?", "my%"). Where("? = 123", bun.Ident("id")). Where("id IN (?)", bun.In([]int64{1, 2, 3})). Where("id IN (?)", subquery). Where("FALSE").WhereOr("TRUE"). WhereGroup(" AND ", func(q *bun.SelectQuery) *bun.SelectQuery { return q.WhereOr("id = 1"). WhereOr("id = 2") }). Returning("*"). Returning("col1, col2"). Returning("NULL"). // don't return anything Exec(ctx) 

Example

To update a row, define a model and use UpdateQueryopen in new window:

book := &Book{ID: 123, Title: "hello"} res, err := db.NewUpdate().Model(book).WherePK().Exec(ctx) 

To update a single column:

book.Title = "hello" res, err := db.NewUpdate(). Model(book). Column("title"). Where("id = ?", 123). Exec(ctx) 
UPDATE books SET title = 'my title' WHERE id = 123 

Alternatively:

res, err := db.NewUpdate(). Model(book). Set("title = ?", "hello"). Where("id = ?", 123). Exec(ctx) 

Bulk-update

To bulk-update books, you can use a CTE:

values := db.NewValues(&[]*Book{book1, book2}) res, err := db.NewUpdate(). With("_data", values). Model((*Book)(nil)). TableExpr("_data"). Set("title = _data.title"). Set("text = _data.text"). Where("book.id = _data.id"). Exec(ctx) 
WITH _data (id, title, text) AS ( VALUES (1, 'title1', 'text1'), (2, 'title2', 'text2') ) UPDATE books AS book SET title = _data.title, text = _data.text FROM _data WHERE book.id = _data.id 

Alternatively, you can use Bulk helper which creates a CTE for you:

res, err := db.NewUpdate(). Model(&books). Column("title", "text"). Bulk(). Exec(ctx) 

Maps

To update using a map[string]interface{}:

value := map[string]interface{}{ "title": "title1", "text": "text1", } res, err := db.NewUpdate(). Model(&value). TableExpr("books"). Where("id = ?", 1). Exec(ctx) 
UPDATE books SET title = 'title1', text = 'text2' WHERE id = 1 

Omit zero values

You can also tell Bun to omit zero struct fields, for example, the following query does not update email column because it contains an empty value:

type User struct {	ID int64	Name string	Email string } res, err := db.NewUpdate(). Model(&User{ID: 1, Name: "John Doe"}). OmitZero(). WherePK(). Exec(ctx) 
UPDATE users SET name = "John Doe" WHERE id = 1 

FQN

Multi-table updates differ in PostgreSQL and MySQL:

-- PostgreSQL UPDATE dest FROM src SET col1 = src.col1 WHERE dest.id = src.id -- MySQL UPDATE dest, src SET dest.col1 = src.col1 WHERE dest.id = src.id 

Bun helps you write queries for both databases by providing SetColumn method:

res, err := db.NewUpdate(). Table("dest", "src"). SetColumn("col1", "src.col1"). Where("dest.id = src.id"). Exec(ctx) 

If you have a slice of models to update, use Bulk method:

res, err := db.NewUpdate(). Model(&models). Column("col1"). Bulk(). Exec(ctx)