entgo的字段名称冲突

在使用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。

猜你喜欢

转载自blog.csdn.net/JosephThatwho/article/details/109066460