遇到问题:BeforeDelete 在删除时获取 SQL 不正确

BeforeDelete 代码如下

go
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
func (t *Target) BeforeDelete(tx *gorm.DB) (err error) {
	// 找到与此 Target 相关的所有 Labels
	var labels []Label
	if err := tx.Model(t).Association("Labels").Find(&labels); err != nil {
		klog.V(4).Infof("Error fetching labels: %v", err)
		return err
	}

	for _, label := range labels {
		if err := tx.Delete(&label).Error; err != nil {
			klog.V(4).Infof("Error deleting label:", err)
			return err
		}
	}

	// 注意:由于设置了 OnDelete:SET NULL,因此在删除 Labels 后,会清理 target_labels 表中的关联
	return nil
}

删除写法

go
1
2
3
4
5
6
7
8
9
func DeleteTargets(target *target.TargetItem) (enconterError error) {
	// 创建 Target
	existingTarget := &Target{}
	if enconterError = DB.Model(&Target{}).Where("address = ? AND metric_path = ? AND scrape_time = ? AND scrape_timeout = ?",
		target.Address, target.MetricPath, target.ScrapeTime, target.ScrapeTimeout).Delete(existingTarget).Error; enconterError != nil {
		return enconterError // 如果找不到记录,则返回错误
	}
	return enconterError
}

删除时遇到的问题:SQL 生成不正确 target_id IN (NULL)

bash
1
2
3
4
BeforeDelete hook triggered

2024/09/22 00:33:36 /mnt/d/src/go/work/prometheus-hub/pkg/model/target.go:37
[0.184ms] [rows:0] SELECT `labels`.`id`,`labels`.`key`,`labels`.`value` FROM `labels` JOIN `target_labels` ON `target_labels`.`label_id` = `labels`.`id` AND `target_labels`.`target_id` IN (NULL) 

问题原因,在删除这条记录时,默认 (t *Target) 必须 id 存在,如果不存在就是 NULL,所以先用 find 查询保证这个操作的 t 中存在主键才可以。

go
1
2
3
4
5
6
7
8
9
func DeleteTargets(target *target.TargetItem) (enconterError error) {
	// 创建 Target
	existingTarget := &Target{}
	if enconterError = DB.Model(&Target{}).Where("address = ? AND metric_path = ? AND scrape_time = ? AND scrape_timeout = ?",
		target.Address, target.MetricPath, target.ScrapeTime, target.ScrapeTimeout).Find(existingTarget).Delete(existingTarget).Error; enconterError != nil {
		return enconterError // 如果找不到记录,则返回错误
	}
	return enconterError
}

修改后的输出 SQL

go
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
2024/09/22 00:41:21 /mnt/d/src/go/work/prometheus-hub/pkg/model/target.go:33
[0.126ms] [rows:3] SELECT `labels`.`id`,`labels`.`key`,`labels`.`value` FROM `labels` JOIN `target_labels` ON `target_labels`.`label_id` = `labels`.`id` AND `target_labels`.`target_id` = 17        

2024/09/22 00:41:21 /mnt/d/src/go/work/prometheus-hub/pkg/model/target.go:39
[5.229ms] [rows:1] DELETE FROM `labels` WHERE `labels`.`id` = 7

2024/09/22 00:41:21 /mnt/d/src/go/work/prometheus-hub/pkg/model/target.go:39
[0.078ms] [rows:1] DELETE FROM `labels` WHERE `labels`.`id` = 8

2024/09/22 00:41:21 /mnt/d/src/go/work/prometheus-hub/pkg/model/target.go:39
[0.062ms] [rows:1] DELETE FROM `labels` WHERE `labels`.`id` = 9

2024/09/22 00:41:21 /mnt/d/src/go/work/prometheus-hub/pkg/model/target.go:70
[15.661ms] [rows:1] DELETE FROM `targets` WHERE (address = "10.0.0.14:9090" AND metric_path = "/metrics" AND scrape_time = 30 AND scrape_timeout = 10) AND `targets`.`id` = 17