在使用facebook开源的orm框架ent.的时候,要避免把字段名定义成Label
。否则在把实例迁移到数据库的时候会导致如下异常:
ent/product/where.go:102:6: Label redeclared in this block
比如定义一张产品表:
{project}/ent/schema/product.go:
package schema
import (
"github.com/facebook/ent"
"github.com/facebook/ent/schema/field"
)
// Product holds the schema definition for the Product entity.
type Product struct {
ent.Schema
}
// Fields of the Product.
func (Product) Fields() []ent.Field {
return []ent.Field{
field.String("name"), // 产品名称
field.String("label"), // 产品标签
}
}
// Edges of the Product.
func (Product) Edges() []ent.Edge {
return nil
}
运行go generate ./ent
命令生成相应的orm代码,会在ent路径下生成名为product的包,package里包含以实体名称命名的文件product.go和实体字段筛选工具where.go
其中product.go中定义了实体的基本字段:
// Code generated by entc, DO NOT EDIT.
package product
const (
// Label holds the string label denoting the product type in the database.
Label = "product"
// FieldID holds the string denoting the id field in the database.
FieldID = "id"
// FieldName holds the string denoting the name field in the database.
FieldName = "name"
// FieldLabel holds the string denoting the label field in the database.
FieldLabel = "label"
// Table holds the table name of the product in the database.
Table = "products"
)
// Columns holds all SQL columns for product fields.
var Columns = []string{
FieldID,
FieldName,
FieldLabel,
}
// ValidColumn reports if the column name is valid (part of the table columns).
func ValidColumn(column string) bool {
for i := range Columns {
if column == Columns[i] {
return true
}
}
return false
}
可以看到里面定义了名为Label的常量。
而在where.go中,给实体的Label字段定义了相关筛选方法:
// Code generated by entc, DO NOT EDIT.
package product
import (
"goorm/ent/predicate"
"github.com/facebook/ent/dialect/sql"
)
...
// Label applies equality check predicate on the "label" field. It's identical to LabelEQ.
func Label(v string) predicate.Product {
return predicate.Product(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldLabel), v))
})
}
...
// LabelEQ applies the EQ predicate on the "label" field.
func LabelEQ(v string) predicate.Product {
return predicate.Product(func(s *sql.Selector) {
s.Where(sql.EQ(s.C(FieldLabel), v))
})
}
...
where.go中首先给label字段定义了一个首字母大写的同名方法Label
用于做值是否相等的比较。
这会导致product包中有两个Label。所以执行数据库迁移会导致以下异常:
ent/product/where.go:102:6: Label redeclared in this block
previous declaration at ent/product/product.go:7:10
这种情况只要把label字段替换成别的名称就可以了,比如product_label。