英文:
How can I use TOML fixtures to seed my database in a development environment using the Go Buffalo framework?
问题
我正在尝试使用 TOML fixtures 在 Go Buffalo 框架中填充我的开发数据库。然而,我在如何做到这一点方面遇到了困难,找不到清晰的示例或文档。
英文:
I am trying to seed my development database in the Go Buffalo framework using TOML fixtures. However, I am having trouble finding a clear example or documentation on how to do this.
答案1
得分: 4
要种子数据库,您可以使用grifts。在创建新应用程序时,应该在grifts/db.go
中生成一个虚拟的占位符grift,看起来像这样:
package grifts
import "github.com/gobuffalo/grift/grift"
var _ = grift.Namespace("db", func() {
grift.Desc("seed", "Seeds a database")
grift.Add("seed", func(c *grift.Context) error {
// 在这里添加数据库种子内容
return nil
})
})
我尝试在grift中使用model.LoadFixture("seed widgets")
,但由于不在测试环境中,所以出现了一些恐慌。我认为直接从toml fixtures中支持数据库种子不是直接支持的,但这将是一个有用的功能。然而,通过查看LoadFixture的代码,我们可以构建自己的fixture加载:
假设您有一个名为name = "seed widgets"
的fixture场景:
package grifts
import (
"fmt"
"os"
"strings"
"github.com/gobuffalo/grift/grift"
"github.com/gobuffalo/suite/v4"
"github.com/gobuffalo/suite/v4/fix"
)
var _ = grift.Namespace("db", func() {
grift.Desc("seed", "Seeds a database")
grift.Add("seed", func(c *grift.Context) error {
// DB连接将连接到在`GO_ENV`中设置的环境(默认为`test`)
// 在您的`.env`文件中将此环境变量设置为`development`
// 注意:最好将种子fixtures放在不同的目录中
// 以分离关注点
model, err := suite.NewModelWithFixtures(os.DirFS("./fixtures"))
if err != nil {
return err
}
sc, err := fix.Find("seed widgets")
if err != nil {
return err
}
for _, table := range sc.Tables {
for _, row := range table.Row {
q := "insert into " + table.Name
keys := []string{}
skeys := []string{}
for k := range row {
keys = append(keys, k)
skeys = append(skeys, ":"+k)
}
q = q + fmt.Sprintf(" (%s) values (%s)", strings.Join(keys, ","), strings.Join(skeys, ","))
if _, err = model.DB.Store.NamedExec(q, row); err != nil {
return err
}
}
}
return nil
})
})
英文:
To seed a database, you can use grifts. When creating a new application, there should be a dummy placeholder grift generated at grifts/db.go
that looks like:
package grifts
import "github.com/gobuffalo/grift/grift"
var _ = grift.Namespace("db", func() {
grift.Desc("seed", "Seeds a database")
grift.Add("seed", func(c *grift.Context) error {
// Add DB seeding stuff here
return nil
})
})
I attempted to use model.LoadFixture("seed widgets")
in a grift, but there is some panic because it is not in a test environment. I think DB seeding from toml fixtures is not supported directly but that would be a useful feature. However looking at the code from LoadFixture, we can construct our own fixture loading:
Assuming you have a fixture with a scenario named name = "seed widgets"
:
package grifts
import (
"fmt"
"os"
"strings"
"github.com/gobuffalo/grift/grift"
"github.com/gobuffalo/suite/v4"
"github.com/gobuffalo/suite/v4/fix"
)
var _ = grift.Namespace("db", func() {
grift.Desc("seed", "Seeds a database")
grift.Add("seed", func(c *grift.Context) error {
// The DB connection will connect to the environment set in `GO_ENV` (defaults to `test`)
// Set this environment variable in your `.env` file to `development`
// NOTE: it may be better to put seed fixtures in a different directory
// to seperate concerns
model, err := suite.NewModelWithFixtures(os.DirFS("./fixtures"))
if err != nil {
return err
}
sc, err := fix.Find("seed widgets")
if err != nil {
return err
}
for _, table := range sc.Tables {
for _, row := range table.Row {
q := "insert into " + table.Name
keys := []string{}
skeys := []string{}
for k := range row {
keys = append(keys, k)
skeys = append(skeys, ":"+k)
}
q = q + fmt.Sprintf(" (%s) values (%s)", strings.Join(keys, ","), strings.Join(skeys, ","))
if _, err = model.DB.Store.NamedExec(q, row); err != nil {
return err
}
}
}
return nil
})
})
答案2
得分: 1
你可以在这里找到关于测试和夹具的所有所需信息:https://github.com/gobuffalo/suite
这是一个关于操作和模型测试的基本示例:
actions/actions_test.go
package actions
import (
"os"
"testing"
"github.com/gobuffalo/suite/v4"
)
type ActionSuite struct {
*suite.Action
}
func Test_ActionSuite(t *testing.T) {
action, err := suite.NewActionWithFixtures(App(), os.DirFS("../fixtures"))
if err != nil {
t.Fatal(err)
}
as := &ActionSuite{
Action: action,
}
suite.Run(t, as)
}
models/models_test.go
package models
import (
"os"
"testing"
"github.com/gobuffalo/suite/v4"
)
type ModelSuite struct {
*suite.Model
}
func Test_ModelSuite(t *testing.T) {
model, err := suite.NewModelWithFixtures(os.DirFS("../fixtures"))
if err != nil {
t.Fatal(err)
}
as := &ModelSuite{
Model: model,
}
suite.Run(t, as)
}
fixtures/widgets.toml
[[scenario]]
name = "lots of widgets"
[[scenario.table]]
name = "widgets"
[[scenario.table.row]]
id = "<%= uuidNamed("widget") %>"
name = "This is widget #1"
body = "some widget body"
created_at = "<%= now() %>"
updated_at = "<%= now() %>"
[[scenario.table.row]]
id = "<%= uuid() %>"
name = "This is widget #2"
body = "some widget body"
created_at = "<%= now() %>"
updated_at = "<%= now() %>"
[[scenario.table]]
name = "users"
[[scenario.table.row]]
id = "<%= uuid() %>"
name = "Mark Bates"
admin = true
price = 19.99
widget_id = "<%= uuidNamed("widget") %>"
created_at = "<%= now() %>"
updated_at = "<%= now() %>"
actions/widgets_test.go
func (as *ActionSuite) Test_WidgetsResource_List() {
as.LoadFixture("lots of widgets")
res := as.HTML("/widgets").Get()
body := res.Body.String()
as.Contains(body, "widget #1")
as.Contains(body, "widget #2")
}
models/widget_test.go
func (ms *ModelSuite) Test_Widget_SomeModelMethod() {
ms.LoadFixture("lots of widgets")
var widgets []Widget
if err := DB.All(&widgets); err != nil {
ms.Fail(err.Error())
}
for _, widget := range widgets {
ms.Equal("some value", widget.SomeModelMethod())
}
}
database.yml
test:
url: {{envOr "TEST_DATABASE_URL" "postgres://postgres@127.0.0.1:5432/medicare_65_quote_test?sslmode=disable"}}
英文:
You can find all the information you need about testing and fixtures here: https://github.com/gobuffalo/suite
Here is a basic example of actions and model tests:
actions/actions_test.go
package actions
import (
"os"
"testing"
"github.com/gobuffalo/suite/v4"
)
type ActionSuite struct {
*suite.Action
}
func Test_ActionSuite(t *testing.T) {
action, err := suite.NewActionWithFixtures(App(), os.DirFS("../fixtures"))
if err != nil {
t.Fatal(err)
}
as := &ActionSuite{
Action: action,
}
suite.Run(t, as)
}
models/models_test.go
package models
import (
"os"
"testing"
"github.com/gobuffalo/suite/v4"
)
type ModelSuite struct {
*suite.Model
}
func Test_ModelSuite(t *testing.T) {
model, err := suite.NewModelWithFixtures(os.DirFS("../fixtures"))
if err != nil {
t.Fatal(err)
}
as := &ModelSuite{
Model: model,
}
suite.Run(t, as)
}
fixtures/widgets.toml
[[scenario]]
name = "lots of widgets"
[[scenario.table]]
name = "widgets"
[[scenario.table.row]]
id = "<%= uuidNamed("widget") %>"
name = "This is widget #1"
body = "some widget body"
created_at = "<%= now() %>"
updated_at = "<%= now() %>"
[[scenario.table.row]]
id = "<%= uuid() %>"
name = "This is widget #2"
body = "some widget body"
created_at = "<%= now() %>"
updated_at = "<%= now() %>"
[[scenario.table]]
name = "users"
[[scenario.table.row]]
id = "<%= uuid() %>"
name = "Mark Bates"
admin = true
price = 19.99
widget_id = "<%= uuidNamed("widget") %>"
created_at = "<%= now() %>"
updated_at = "<%= now() %>"
actions/widgets_test.go
func (as *ActionSuite) Test_WidgetsResource_List() {
as.LoadFixture("lots of widgets")
res := as.HTML("/widgets").Get()
body := res.Body.String()
as.Contains(body, "widget #1")
as.Contains(body, "widget #2")
}
models/widget_test.go
func (ms *ModelSuite) Test_Widget_SomeModelMethod() {
ms.LoadFixture("lots of widgets")
var widgets []Widget
if err := DB.All(&widgets); err != nil {
ms.Fail(err.Error())
}
for _, widget := range widgets {
ms.Equal("some value", widget.SomeModelMethod())
}
}
database.yml
test:
url: {{envOr "TEST_DATABASE_URL" "postgres://postgres@127.0.0.1:5432/medicare_65_quote_test?sslmode=disable"}}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论