前几天在使用Beego的ORM往Mysql中写入数据时失败,这里记录下原因。

当时代码是这样写的

o,err := orm.NewOrm()
if err!=nil{
    return err
}

record := &models.User{}
err=o.Insert(&record)
if err!=nil {
    return err
}

在执行此代码报错,错误信息:

<Ormer> table: `.` not found, maybe not RegisterModel

上面代码的错误性是否非常明显的,是因为本身record是指针对性,而在Insert时又传入的是指针的指针&record

来看下Beego ORM 内部是如何获取表名的

源代码如下:

// get model info and model reflect value
func (o *orm) getMiInd(md interface{}, needPtr bool) (mi *modelInfo, ind reflect.Value) {
	val := reflect.ValueOf(md)
	ind = reflect.Indirect(val)
	typ := ind.Type()
	if needPtr && val.Kind() != reflect.Ptr {
		panic(fmt.Errorf("<Ormer> cannot use non-ptr model struct `%s`", getFullName(typ)))
	}
	name := getFullName(typ)
	if mi, ok := modelCache.getByFN(name); ok {
		return mi, ind
	}
	panic(fmt.Errorf("<Ormer> table: `%s` not found, maybe not RegisterModel", name))
}

// insert model data to database
func (o *orm) Insert(md interface{}) (int64, error) {
	mi, ind := o.getMiInd(md, true)
	id, err := o.alias.DbBaser.Insert(o.db, mi, ind, o.alias.TZ)
	if err != nil {
		return id, err
	}

	o.setPk(mi, ind, id)

	return id, nil
}

通过反射查找record类型,并获取该类型的名称,但因为传入的并非对性的指针,导致获取相应类型的名称是出差。

如下测试:

综合上述,在传入对象时,只能转入对象的指针,这样才能保证通过反射获取相关数据是正确合理的。

上面就是解决在使用beego的ORM框架时报错的分析经过。