jjzjj

SQLite、Golang 和联结表

coder 2024-07-10 原文

我想使用 Go 和 sqlite 创建一个小型图书数据库。我从这条建议中得到了主要建议 SQLite foreign key examples并对其进行了一些重新开发。

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()

麻烦来了——如果我添加多于同一作者的一本书,a_id 会增加,但连接表包含它的旧值。 例如:

Books:                       
id | Title                   
---|--------------------
1  | Atlas Shrugged pt.1 
2  | Atlas Shrugged pt.2
3  | Atlas Shrugged pt.3

Authors:
id | Fname | Mname | Lname 
---|-------|-------|------
702| Ayn   |       | Rand

Junction table:
BookId | AuthorID
-------|---------
 1     |  700
 2     |  701
 3     |  702

What I want - Junction table:
BookId | AuthorID
-------|---------
 1     |  702
 2     |  702
 3     |  702

我该如何修复它,以便正确的 AuthorId 反射(reflect)在表格中?我不想使用 GORM 或任何 ORM 工具并尝试使用纯(或多或少)SQL 来解决它。

我现在看到的解决方案之一是,我可以先选择,如果没有找到则插入,然后再次选择,但是我不确定这个想法是多么地道。请注意,我有相当多的记录要添加。

最佳答案

我的建议是 SELECT 您的作者列表,INSERT 缺少的作者。该解决方案很幼稚,但它有效且简单。 我不是最新的 SQLite 关系特性,但使用它们并不总是处理外键的最简单方法......

现在,如果您要处理大量数据,请执行相同的操作,但首先合并您的书籍作者,这样您就可以只有一个 SELECT 然后一个 INSERT 去做。

关于SQLite、Golang 和联结表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35410494/

有关SQLite、Golang 和联结表的更多相关文章

  1. ruby - Sinatra + Heroku + Datamapper 使用 dm-sqlite-adapter 部署问题 - 2

    出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t

  2. ruby - 创建新数据库时 DataMapper SQLite 错误 - 2

    我是Sinatra的新手,我正在尝试使用SQLite3和Datamapper创建一个数据库。我安装了gem和适配器,然后尝试在文件中执行此代码:#configrequire'sinatra'require'sinatra/contrib'ifdevelopment?require'data_mapper'DataMapper::setup(:default,"sqlite3://#{Dir.pwd}/recall.db")DataMapper.finalize.auto_upgrade!当我执行文件时,命令行给了我这个错误:C:/Ruby193/lib/ruby/site_ruby/1

  3. ruby - Rails 3 不会用 rvm 安装 sqlite3-ruby gem? - 2

    我正在试用rvm,并用它安装了ruby​​1.9.2和rails3。我需要重新安装sqlite3-rubygem(因为rvm为不同版本的ruby​​将所有gem分开)。问题是,当我尝试时,我得到:geminstallsqlite3-ruby/home/jenny/.rvm/rubies/ruby-1.9.2-p0/bin/gem:4:warning:Insecureworldwritabledir/home/jenny/.rvm/gems/ruby-1.9.2-p0/bininPATH,mode040777Buildingnativeextensions.Thiscouldtakeaw

  4. Ruby Guard 问题 - 'Please install the sqlite3 adapter' - railstutorial.org - 2

    我正在关注RubyonRailsTutorial并且在测试部分变得有些困惑,特别是-3.6.2-AutomatedtestswithGuard按照部署到Heroku的教程说明,我已切换到Postgresql并从我的gemfile中删除了sqlite3,并进行了捆绑安装以进行更新。但是,一旦我运行bundleexecguard我收到消息:/Users/username/.rvm/gems/ruby-1.9.3-p125@global/gems/bundler-1.1.3/lib/bundler/rubygems_integration.rb:147:inblockinreplace_ge

  5. ruby - 安装 sqlite3-ruby 时出现问题! - 2

    我在crunchbanglinux上安装sqlite3-rubygem时遇到问题。在谷歌搜索过去几个小时并关注了几个遇到同样问题的人之后,我仍然没有让它工作。这是我在尝试“sudogeminstallsqlite3-ruby”后看到的构建native扩展。这可能需要一段时间...错误:安装sqlite3-ruby时出错:错误:无法构建gemnative扩展。/usr/bin/ruby1.8extconf.rb检查sqlite3.h...是的在-lsqlite3中检查sqlite3_libversion_number()...是检查rb_proc_arity()...否检查sqlite3

  6. javascript - 如何使用 Cordova 将 Sqlite 数据同步到 sql server - 2

    嗨,这么多天以来,我一直在搜索这个主题,但也无法得到提示。如果有人知道如何使用cordova和javascript将sqlite数据同步到sqlserver,请帮忙 最佳答案 开源实现有一些开源项目可以将PhoneGap应用程序与远程服务器同步。但是您必须调整/实现以适合您的项目。SynchronizealocalWebSQLDbtoaserverCouchbaseLitePhoneGappluginPouchdb或者,自定义API您可以创建自己的API方法集,以将数据从WebSQL发送/更新到您的远程服务器DB。标记需要“同步”到

  7. 关于Android Studio查看SQLite数据库 - 2

    连接SQLite数据库对于as内部模拟器可以使用AppInspection,支持API26版本以上优点:这种是最方便的可以实时查看数据表的变化缺点:仅支持内部模拟器,需要安装的东西比较多,很慢,机器性能不好很卡顿对于第三方模拟器可以通过DeviceFileExplorer找到app的.db文件进行查看.db生成位置和名称需要配置来判断litepal.xml-->-->-->-->.db文件在模拟器中的位置需要安装插件,或者其他软件查看数据,不能实时查询具体方法是找到.db文件双击会在电脑的磁盘上生成一个复制的文件(或者直接从模拟器文件夹中将文件复制出来),此时通过DatabaseNavigat

  8. 华为OD机试Golang解题 - 任务总执行时长 - 2

    华为Od必看系列华为OD机试全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理已参加机试人员的实战技巧华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典文章目录华为Od必看系列使用说明本期题目:任务总执行时长题目输入输出示例一输入输出说明go代码实现华为OD其它语言版本

  9. 【编程实践】Golang 获取HTTP请求的IP地址 - 2

    目录Golang获取HTTP请求的IP地址HTTP的发展历史3,HTTP所在的网络层次4,HTTP请求与响应

  10. Golang SQL 查询语法 - 2

    关闭。这个问题需要debuggingdetails.它目前不接受答案。编辑问题以包含desiredbehavior,aspecificproblemorerror,andtheshortestcodenecessarytoreproducetheproblem.这将有助于其他人回答问题。关闭4年前。Improvethisquestion在golang代码中使用sql查询获取语法错误。golang中此SQL查询所需的正确语法:rows,errQuery:=dbCon.Query("SELECTB.LatestDate,A.SVRNameASServerName,A.DRIVE,A.Tot

随机推荐