简体   繁体   English

如何在使用 Go Buffalo 框架的开发环境中使用 TOML fixtures 为我的数据库播种?

[英]How can I use TOML fixtures to seed my database in a development environment using the Go Buffalo framework?

I am trying to seed my development database in the Go Buffalo framework using TOML fixtures.我正在尝试使用 TOML 固定装置在 Go Buffalo 框架中播种我的开发数据库。 However, I am having trouble finding a clear example or documentation on how to do this.但是,我无法找到有关如何执行此操作的明确示例或文档。

To seed a database, you can use grifts.要为数据库播种,您可以使用 grifts。 When creating a new application, there should be a dummy placeholder grift generated at grifts/db.go that looks like:创建新应用程序时,应该会在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 {
        // 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.我试图在 grift 中使用model.LoadFixture("seed widgets") ,但由于它不在测试环境中,所以有些恐慌。 I think DB seeding from toml fixtures is not supported directly but that would be a useful feature.我认为不直接支持来自 toml fixtures 的 DB seeding,但这将是一个有用的功能。 However looking at the code from LoadFixture , we can construct our own fixture loading:但是查看LoadFixture的代码,我们可以构建自己的夹具加载:

Assuming you have a fixture with a scenario named name = "seed widgets" :假设您有一个名为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
    })

})

You can find all the information you need about testing and fixtures here: https://github.com/gobuffalo/suite您可以在此处找到有关测试和固定装置所需的所有信息: https://github.com/gobuffalo/suite

Here is a basic example of actions and model tests:这是操作和 model 测试的基本示例:

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"}}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM