我写了一个玩具应用程序来试验通过sqlx使用Postgresql。我使用
进行了大量插入工作pq.CopyIn
作为预备陈述的内容
stmt, _ := tx.Preparex(pq.CopyIn(tablename, column, column, ...)
然后我会继续向我正在创建的大量插入添加行。
tx.Exec(..., ..., ...)
然后最终执行准备好的声明
stmt.Exec()
这之前完美无缺,但现在我回到它并尝试执行此代码,它挂在
上stmt.Exec
我在代码中遗漏了什么,或者这与数据库引擎有关,没有响应。
这是我的完整代码。
package main
import (
_ "database/sql"
"fmt"
"log"
"encoding/json"
"io/ioutil"
"os"
"github.com/jmoiron/sqlx"
"github.com/lib/pq"
)
var schema = `
CREATE TABLE IF NOT EXISTS contact (
id Serial,
first_name text,
last_name text,
email text
);`
type Contact struct {
Id int `json:"-"`
First_name string `json:"first_name"`
Last_name string `json:"last_name"`
Email string `json:"email"`
}
type Contacts struct {
Contacts []Contact `json:"contacts"`
}
func (c *Contacts) createFromJSON(json_str []byte) error {
b := []byte(json_str)
err := json.Unmarshal(b, &c)
if err != nil {
log.Fatal(err)
}
return err
}
func (c *Contacts) save(db *sqlx.DB) error {
tx := db.MustBegin()
stmt, _ := tx.Preparex(pq.CopyIn("contact", "first_name", "last_name", "email"))
for _, contact := range c.Contacts {
tx.Exec(contact.First_name, contact.Last_name, contact.Email)
}
_, err := stmt.Exec()
if err != nil {
log.Fatal(err)
return err
}
err = stmt.Close()
if err != nil {
log.Fatal(err)
return err
}
tx.Commit()
return nil
}
func connect() (*sqlx.DB, error) {
db, err := sqlx.Connect("postgres", "user=pqgotest dbname=pqgotest sslmode=disable")
if err != nil {
log.Fatal(err)
}
return db, err
}
func createTables(db *sqlx.DB) {
db.MustExec(schema)
}
func main() {
db, err := connect()
if err != nil {
os.Exit(1)
}
createTables(db)
contactsJson, e := ioutil.ReadFile("./contacts.json")
if e != nil {
fmt.Printf("File error: %v\n", e)
os.Exit(1)
}
tx := db.MustBegin()
tx.MustExec("DELETE FROM contact")
tx.Commit()
contacts := new(Contacts)
contacts.createFromJSON(contactsJson)
contacts.save(db)
people := new(Contacts)
db.Select(people.Contacts, "SELECT * FROM contact ORDER BY email,id ASC")
for _, contact := range people.Contacts {
contact_json, err := json.Marshal(contact)
if err != nil {
log.Fatal(err)
os.Exit(1)
}
fmt.Printf("%s\n", contact_json)
}
}
我也可以包含contacts.json文件的内容,如果有帮助的话。
更新
是的,最终显而易见。我是从tx创建一个声明,
stmt, _ := tx.Preparex(pq.CopyIn(tablename, column, column, ...)
并且对此进一步增加应该是stmt
stmt.Exec(..., ..., ...)
另一个与问题没有直接关系的错误是我将一组联系人插入struct Contacts的Contacts字段中
people := new(Contacts)
db.Select(people.Contacts, "SELECT * FROM contact ORDER BY email,id ASC")
应该将指针传递给Contacts的Contacts数组字段的db的Select方法,如此
db.Select(&people.Contacts, "SELECT * FROM contact ORDER BY email,id ASC")
如果人们稍后尝试运行此代码,并想知道为什么它不会将结果打印到控制台。
答案 0 :(得分:1)
从https://godoc.org/github.com/lib/pq中的批量导入部分,它应该是
stmt.Exec(contact.First_name, contact.Last_name, contact.Email)