GORM allows to delete objects using primary key(s) with inline condition, it works with numbers, check out Query Inline Conditions for details
// DELETE FROM users WHERE id = 10;
db.Delete(&User{}, "10")
// DELETE FROM users WHERE id = 10;
db.Delete(&users, []int{1,2,3})
// DELETE FROM users WHERE id IN (1,2,3);
GORM allows hooks BeforeDelete
, AfterDelete
, those methods will be called when deleting a record, refer for details
func (u *User) BeforeDelete(tx *gorm.DB) (err error) {
if u.Role == "admin" {
return errors.New("admin user not allowed to delete")
}
return
The specified value has no primary value, GORM will perform a batch delete, it will delete all matched records
db.Where("email LIKE ?", "%jinzhu%").Delete(&Email{})
// DELETE from emails where email LIKE "%jinzhu%";
db.Delete(&Email{}, "email LIKE ?", "%jinzhu%")
// DELETE from emails where email LIKE "%jinzhu%";
If you perform a batch delete without any conditions, GORM WON’T run it, and will return ErrMissingWhereClause
error
You have to use some conditions or use raw SQL or enable AllowGlobalUpdate
mode, for example:
// return all columns
var users []User
DB.Clauses(clause.Returning{}).Where("role = ?", "admin").Delete(&users)
// users => []User{{ID: 1, Name: "jinzhu", Role: "admin", Salary: 100}, {ID: 2, Name: "jinzhu.2", Role: "admin", Salary: 1000}}
// return specified columns
DB.Clauses(clause.Returning{Columns: []clause.Column{{Name: "name"}, {Name: "salary"}}}).Where("role = ?", "admin").Delete(&users)
// DELETE FROM `users` WHERE role = "admin" RETURNING `name`, `salary`
// users => []User{{ID: 0, Name: "jinzhu", Role: "", Salary: 100}, {ID: 0, Name: "jinzhu.2", Role: "", Salary: 1000}}
If your model includes a gorm.DeletedAt
field (which is included in gorm.Model
), it will get soft delete ability automatically!
When calling Delete
, the record WON’T be removed from the database, but GORM will set the DeletedAt
‘s value to the current time, and the data is not findable with normal Query methods anymore.
// user's ID is `111`
db.Delete(&user)
// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE id = 111;
// Batch Delete
db.Where("age = ?", 20).Delete(&User{})
// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE age = 20;
// Soft deleted records will be ignored when querying
db.Where("age = 20").Find(&user)
// SELECT * FROM users WHERE age = 20 AND deleted_at IS NULL;
If you don’t want to include gorm.Model
, you can enable the soft delete feature like:
type User struct {
ID int
Deleted gorm.DeletedAt
}
You can find soft deleted records with Unscoped
You can delete matched records permanently with Unscoped
db.Unscoped().Delete(&order)
// DELETE FROM orders WHERE id=10;
import "gorm.io/plugin/soft_delete"
type User struct {
ID uint
Name string
DeletedAt soft_delete.DeletedAt
}
// Query
SELECT * FROM users WHERE deleted_at = 0;
// Delete
type User struct {
ID uint
Name string
gorm:"uniqueIndex:udx_name"
DeletedAt soft_delete.DeletedAt gorm:"uniqueIndex:udx_name"
}
Use 1
/ as delete flag