0

我有一个 postgres 数据库,我想为它生成表并使用 Gorp 写入,但是当我尝试插入时收到一条错误消息,因为我的结构中包含切片“sql:转换参数 $4 类型:不支持的类型 [] core.EmbeddedStruct,结构切片。

我的结构如下所示:

type Struct1 struct {
	ID              string
	Name            string
	Location        string
	EmbeddedStruct  []EmbeddedStruct
}

type EmbeddedStruct struct {
	ID         string
	Name       string
	struct1Id  string
	EmbeddedStruct2  []EmbeddedStruct2
}

type EmbeddedStruct2 struct {
	ID               string
	Name             string
	embeddedStructId string
}

func (repo *PgStruct1Repo) Write(t *core.Struct1) error {
	trans, err := createTransaction(repo.dbMap)
	defer closeTransaction(trans)

	if err != nil {
		return err
	}

	// Check to see if struct1 item already exists
	exists, err := repo.exists(t.ID, trans)
	if err != nil {
		return err
	}

	if !exists {
		log.Debugf("saving new struct1 with ID %s", t.ID)
		err = trans.Insert(t)
		if err != nil {
			return err
		}
		return nil
	}

	return nil
}

有没有人有任何经验/或知道 Gorp 是否支持插入切片?从我读过的内容来看,它似乎只支持 SELECT 语句的切片

4

1 回答 1

1

Gorp 支持插入可变数量的切片,所以如果你有一个切片records,你可以这样做:

 err = db.Insert(records...)

但是,从您的问题来看,您似乎想保存一条具有 slice 结构字段的记录。

https://github.com/go-gorp/gorp

gorp 对结构之间的关系一无所知(至少现在还不知道)。

所以,你必须自己处理这种关系。我个人解决这个问题的方法是让Gorp 忽略 parent 上的切片

type Struct1 struct {
    ID              string
    Name            string
    Location        string
    EmbeddedStruct  []EmbeddedStruct `db:"-"`
}

然后使用PostInsert 钩子保存EmbeddedStruct(旁注,这是一个糟糕的名字,因为它实际上不是嵌入式结构

func (s *Struct1) PostInsert(sql gorp.SqlExecutor) error {
    for i := range s.EmbeddedStruct {
        s.EmbeddedStruct[i].struct1Id = s.ID
    }
    return sql.Insert(s.EmbeddedStruct...)
}

然后重复这个过程EmbeddedStruct2

注意在数据库端正确设置关系以确保引用完整性(例如 ON DELETE CASCADE / RESTRICT),将整个事物包装在事务中可能是个好主意。

于 2019-11-20T22:58:02.437 回答