doumindang2416 2016-11-02 11:50
浏览 151
已采纳

为什么此sqlx的copyin语句挂起?

I've written a toy app to experiment with using Postgresql through sqlx. I got a mass insert working using

pq.CopyIn

as content of a prepared statement

stmt, _ := tx.Preparex(pq.CopyIn(tablename, column, column, ...)

I would then proceed to add rows to the mass insert I'm creating.

tx.Exec(..., ..., ...)

then finally execute the prepared statement

stmt.Exec()

This worked perfectly before, but now I've come back to it and try and execute this code, it hangs on the

stmt.Exec

Am I missing something in my code or is this all to do with the Database Engine, being unresponsive.

Here's my full code for this.

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
", 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
", contact_json)
    }


}

I could include the contents of the contacts.json file as well, if that will help.

UPDATE

Yes it was obvious in the end. I was creating a statement from tx,

stmt, _ := tx.Preparex(pq.CopyIn(tablename, column, column, ...)

and further additions to this should be to stmt

stmt.Exec(..., ..., ...)

Also another error not directly related to the question is where I insert an array of contacts into the Contacts field of the struct Contacts

people := new(Contacts)
db.Select(people.Contacts, "SELECT * FROM contact ORDER BY email,id ASC")

should be passing a pointer to the Select method of db of the Contacts array field of Contacts, like so

db.Select(&people.Contacts, "SELECT * FROM contact ORDER BY email,id ASC")

In case people try and run this code later and wonder why it's not printing the results to the console.

  • 写回答

1条回答 默认 最新

  • doufuhao0566 2016-11-02 17:49
    关注

    From Bulk imports part in https://godoc.org/github.com/lib/pq, it should be

    stmt.Exec(contact.First_name, contact.Last_name, contact.Email)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 完全没有学习过GAN,看了CSDN的一篇文章,里面有代码但是完全不知道如何操作
  • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
  • ¥20 软件测试决策法疑问求解答
  • ¥15 win11 23H2删除推荐的项目,支持注册表等
  • ¥15 matlab 用yalmip搭建模型,cplex求解,线性化处理的方法
  • ¥15 qt6.6.3 基于百度云的语音识别 不会改
  • ¥15 关于#目标检测#的问题:大概就是类似后台自动检测某下架商品的库存,在他监测到该商品上架并且可以购买的瞬间点击立即购买下单
  • ¥15 神经网络怎么把隐含层变量融合到损失函数中?
  • ¥15 lingo18勾选global solver求解使用的算法
  • ¥15 全部备份安卓app数据包括密码,可以复制到另一手机上运行