帮同事排查一个gorm导入数据报错的问题
事发现场
ck sql
CREATE TABLE ods_api.t_sms_jg_msg_callback_dis
(
`app_key` String DEFAULT '' COMMENT '应用标识',
`callback_type` Int32 DEFAULT 0 COMMENT '0送达,1回执',
`channel` Int32 DEFAULT 0 COMMENT 'uid下发的渠道',
`model` String DEFAULT '' COMMENT '设备机型',
`jgid` String DEFAULT '' COMMENT '极光返回的msgid',
`notification_state` Int8 DEFAULT 0 COMMENT '接收通知时通知开关是否打开',
`params` String DEFAULT '' COMMENT '用户在push API推送请求的时候在payload的callback里自行指定的参数',
`platform` String DEFAULT '' COMMENT '推送平台',
`registration_id` String DEFAULT '' COMMENT '设备唯一标识',
`alias` String DEFAULT '' COMMENT '设备registration_id对应的别名',
`send_time` String DEFAULT '' COMMENT '通知的送达时间/ 用户点击通知的时间',
`created_at` DateTime DEFAULT now()
)
ENGINE = ReplacingMergeTree(created_at)
PARTITION BY toDate(created_at)
ORDER BY (callback_type, jgid, registration_id, send_time)
SETTINGS index_granularity = 8192
COMMENT '极光push点击/送达回执记录表,中台notify服务用'
go 数据表
type TSmsJgMsgCallback struct {
AppKey string `gorm:"column:app_key;default:;comment:'应用标识'" json:"appkey"`
CallbackType int32 `gorm:"column:callback_type;default:0;comment:'0送达,1回执'" json:"callback_type"`
Channel int32 `gorm:"column:channel;default:0;comment:'uid下发的渠道'" json:"channel"`
Model string `gorm:"column:model;default:;comment:'设备机型'" json:"model"`
Jgid string `gorm:"column:jgid;default:;comment:'极光返回的msgid'" json:"msgid"`
NotificationState int8 `gorm:"column:notification_state;default:0;comment:'接收通知时通知开关是否打开'" json:"notification_state"`
Params string `gorm:"column:params;default:;comment:'用户在push API推送请求的时候在payload的callback里自行指定的参数'" json:"params"`
Platform string `gorm:"column:platform;default:;comment:'推送平台'" json:"platform"`
RegistrationId string `gorm:"column:registration_id;default:;comment:'设备唯一标识'" json:"registration_id"`
Alias string `gorm:"column:alias;default:;comment:'设备registration_id对应的别名'" json:"alias"`
SendTime string `gorm:"column:send_time;default:;comment:'通知的送达时间/ 用户点击通知的时间'" json:"send_time"`
CreatedAt time.Time `gorm:"column:created_at"`
}
func (t *TSmsJgMsgCallback) TableName() string {
return "t_sms_jg_msg_callback_dis"
}
导入数据报错代码
func insertCk(callbackList []ck.TSmsJgMsgCallback) {
if len(callbackList) == 0 {
return
}
err := clickhouse.GetPushCk().Table((&ck.TSmsJgMsgCallback{}).TableName()).Create(&callbackList).Error
if err != nil {
logger.Error("callbackClick insertCk err", zap.Error(err), zap.Any("callbackList", callbackList))
return
}
日志打印:
INSERT INTO `t_sms_jg_msg_callback` (`callback_type`,`channel`,`notification_state`,`alias`,`send_time`,`app_key`,`model`,`jgid`,`params`,`platform`,`registration_id`) VALUES (1,1,1,'alias1','1510109259','b2d7e0fbaa7f4d7e9c2b3bc0','model1','123','{"key1":"value1","key2":"value2"}','android','1a0018970a4b4b4b4b4b4b4b4b4b4b4b')
callbackClick ck insert err {"error": "alias (String): unexpected type clause.Expr"
问题分析
从sql日志和手动执行,并无问题,只能找gorm clihouse源码debug分析为什么报类型不一致
可以看到,变量里jgid字段类型不为string,而是为DEFAULT?
变量类型为[]interface{} ?
再看gorm的定义
gorm语法写错了
总结
通过SQL自动生成自动代码model时,尽量用公司内部的组件或者可靠的三方工具,自己写非常容易出错