猿问

SQLite、Golang 和连接表

我想使用 Go 和 sqlite 创建一个小型书籍数据库。我从这个建议SQLite 外键示例中获取主要内容并对其进行了一些重新开发。


package main                                                                                                                                                


import (

    "database/sql"

...

    _ "github.com/mattn/go-sqlite3"

)


...

db, err := sql.Open("sqlite3", "./foo.db")

if err != nil {

    log.Fatal(err)

}

defer db.Close()


sqlStmt := `

    create table books (

        id integer primary key autoincrement, 

        title text

    );


    create table booksauthors ( 

        bookid integer references books(id), 

        uthorid integer references authors(id) ON DELETE CASCADE ON UPDATE CASCADE

    );


    create table authors (

        id integer primary key autoincrement, 

        fname text, 

        mname text,

        lname text,

        unique (fname, mname, lname) on conflict ignore

    );

`

因此,我想保留唯一作者的列表并与书籍表保持多对多连接(一本书可能有多个作者,而作者可能写了多个书)。


然后我简单地循环添加书籍,获取 LastIndexID 并将其放入连接表(代码减少用于说明,b 是书籍结构):


tx, err := db.Begin()

if err != nil {

    log.Fatal(err)

}


res, err := db.Exec("Insert into books(title) values(?)", b.Title)

if err != nil {

    log.Fatal(err)

}

b_id, _ := res.LastInsertId()

for _, a := range b.Authors {

    res, err = db.Exec("Insert into authors(fname, mname, lname) values(?, ?, ?)", a.Fname, a.Mname, a.Lname)

    if err != nil {

        log.Fatal(err)

    }

    a_id, _ := res.LastInsertId()

    fmt.Println(a_id, b_id, a)


    res, err = db.Exec("Insert into booksauthors(bookid, authorid) values(?, ?)", b_id, a_id)

    if err != nil {

        log.Fatal(err)

    }

}

tx.Commit()


翻过高山走不出你
浏览 219回答 2
2回答

慕斯王

作为一个快速的'n'dirty hack,我在添加了一个作者后做了一个选择:err = db.QueryRow("select id from authors where fname = ? and mname = ? and lname = ?", a.Fname, a.Mname, a.Lname).Scan(&a_id)if err != nil {    log.Fatal(err)}res, err = db.Exec("Insert into booksauthors(bookid, authorid) values(?, ?)", b_id, a_id)if err != nil {    enter code herelog.Fatal(err)}但我仍在寻找更好的答案......

米琪卡哇伊

我的建议是给SELECT你列出作者和INSERT遗漏的名单。该解决方案很幼稚,但它有效且简单。我不是最新的 SQLite 关系特性,但使用它们并不总是处理外键的最简单方法......。现在,如果你有一个大批量数据的过程中,做同样的操作,但是通过合并你的书的作者开始,所以你只能有一个SELECT再一个INSERT的事情。
随时随地看视频慕课网APP

相关分类

Go
我要回答