夹具
您可以使用夹具将初始数据加载到数据库中,以进行测试或演示目的。您可以使用 YAML 格式编写夹具,并根据需要从测试或基于 Go 的 迁移 中加载它们。
创建夹具
夹具是一个简单的 YAML 文件,可以使用 text/template 表达式生成值。Bun 使用 yaml.v3 将 YAML 数据反序列化为 Go 模型,然后将模型保存在数据库中。
以下是 User 模型的夹具示例
- model: User
rows:
- name: John Smith
email: john@smith.com
created_at: '{{ now }}'
- name: Jonh Doe
email: john@doe.com
created_at: '{{ now }}'
单个夹具可以包含多个模型的数据。您还可以使用 _id
字段为行命名,并使用 text/template 语法从其他模型中引用它们
- model: User
rows:
- _id: smith
name: John Smith
email: john@smith.com
created_at: '{{ now }}'
- _id: doe
name: Jonh Doe
email: john@doe.com
created_at: '{{ now }}'
- model: Org
rows:
- name: "{{ $.User.smith.Name }}'s Org"
owner_id: '{{ $.User.smith.ID }}'
- name: "{{ $.User.doe.Name }}'s Org"
owner_id: '{{ $.User.doe.ID }}'
加载夹具
假设夹具存储在 testdata/fixture.yml
中,您可以使用以下代码加载它
// Let the db know about the models.
db.RegisterModel((*User)(nil), (*Org)(nil))
fixture := dbfixture.New(db)
err := fixture.Load(ctx, os.DirFS("testdata"), "fixture.yml")
通过使用 fixture.WithRecreateTables()
选项,您可以使 bun 删除现有表并用新表替换它们。或者,您可以使用 fixture.WithTruncateTables()
选项来截断表。
fixture := dbfixture.New(db, dbfixture.WithRecreateTables())
fixture := dbfixture.New(db, dbfixture.WithTruncateTables())
您还可以注册并在夹具中使用自定义模板函数
funcMap := template.FuncMap{
"now": func() string {
return time.Now().Format(time.RFC3339Nano)
},
}
fixture := dbfixture.New(db, dbfixture.WithTemplateFuncs(funcMap))
检索夹具数据
稍后,您可以使用 Row
和 MustRow
方法检索加载的模型
fmt.Println("Smith", fixture.MustRow("User.smith").(*User))
您还可以通过主键检索没有 _id
字段的行
fmt.Println("Org with id=1", fixture.MustRow("Org.pk1").(*Org))
字段名称
Bun 使用 SQL 列名查找匹配的结构体字段,然后调用 yaml.v3 来反序列化数据。因此,当反序列化到结构体字段时,您可能需要使用 yaml
标签来覆盖默认的 YAML 字段名称。
type User struct {
ID int64 `bun:",pk,autoincrement"`
Params UserParams `bun:"type:jsonb"`
}
type UserParams struct {
Param1 string `yaml:"param1"`
Param2 string `yaml:"param2"`
}
源代码
您可以在 GitHub 上找到上述示例的源代码。