Go 实现 Database Seeder

Go 实现 Database Seeder

之前使用 Laravel 提供的 Seeder 感觉很方便,这时 Seeder 就有了用武之地,可以快速填充系统必要数据。如:菜单、权限等。

定义 Seeder 接口

1
2
3
4
5
6
7
8
9
10
11
package models

type (
Seeder interface {
Seed() error
}
Model interface {
Store() error
Update(id string) error
}
)

定义模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
type Menu struct {
Code string `xorm:"not null pk comment('编码') VARCHAR(255)"`
ParentCode string `xorm:"not null comment('父编码') index VARCHAR(255)"`
PermissionCode string `xorm:"not null comment('权限编码') index VARCHAR(255)"`
Name string `xorm:"not null comment('名称') VARCHAR(255)"`
Route string `xorm:"not null comment('前端路由') VARCHAR(255)"`
Icon string `xorm:"not null comment('图标') VARCHAR(255)"`
}

// 定义模型的数据表名称
func (menu *Menu) TableName() string {
return "menus"
}

// 数据填充器
func (menu *Menu) Seed() error {
return menu.Store()
}

// 创建菜单
func (menu *Menu) Store() error {
_, err := Engine.Insert(menu)
return err
}

定义 Seeder 注册接口和 Seeder 结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package seeds

import (
"github.com/betterde/ects/models"
"log"
)

type (
SeederInterface interface {
Register(seeder *Seeder)
}

Seeder struct {
instances []models.Seeder
}
)

func (seeder *Seeder) Run() error {
seeders := []SeederInterface{
&MenuSeeder{},
&PermissionSeeder{},
}

for _, item := range seeders {
item.Register(seeder)
}

for _, instalce := range seeder.instances {
if err := instalce.Seed(); err != nil {
log.Println(err)
}
}
return nil
}

实现模型的填充方法

实现菜单模型的 Register 方法,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package seeds

import "github.com/betterde/ects/models"

type (
MenuSeeder struct {
}
)

func (menus *MenuSeeder) Register(seeder *Seeder) {
items := []models.Seeder{
&models.Menu{
Code: "dashboard",
ParentCode: "",
PermissionCode: "dashboard",
Name: "概览",
Route: "/dashboard",
Icon: "",
},
&models.Menu{
Code: "task",
ParentCode: "",
PermissionCode: "task",
Name: "任务",
Route: "/task",
Icon: "",
},
&models.Menu{
Code: "worker",
ParentCode: "",
PermissionCode: "worker",
Name: "节点",
Route: "/worker",
Icon: "",
},
&models.Menu{
Code: "team",
ParentCode: "",
PermissionCode: "team",
Name: "团队",
Route: "/team",
Icon: "",
},
&models.Menu{
Code: "user",
ParentCode: "",
PermissionCode: "user",
Name: "用户",
Route: "/user",
Icon: "",
},
&models.Menu{
Code: "log",
ParentCode: "",
PermissionCode: "log",
Name: "日志",
Route: "/log",
Icon: "",
},
&models.Menu{
Code: "record",
ParentCode: "",
PermissionCode: "record",
Name: "记录",
Route: "/record",
Icon: "",
},
&models.Menu{
Code: "setting",
ParentCode: "",
PermissionCode: "setting",
Name: "设置",
Route: "/setting",
Icon: "",
},
}

seeder.instances = append(seeder.instances, items...)
}

在服务启动时调用

1
2
3
4
seedService := seeds.Seeder{}
if err := seedService.Run(); err != nil {
return response.InternalServerError("Failed to seed system data", err)
}

评论