• MIT6.5830 Lab0-Go tutorial实验记录(二)


    MIT6.5830 Lab0-Go tutorial实验记录(二) – WhiteNight's Site

    标签:Golang, 数据库

    在将数据库的数据转换为图表前,我们需要先测试是否能正常访问数据库文件。

    写者注

    为什么要怎么做?因为这块 非常容易出问题。在handlers中需要我们连接至数据库,并将数据转换为图片呈现在前端的html页面上。
    问题在于这里各种报错原因都有,而且在lab0原本的代码上进行调试非常折磨,断点经常要打上一堆。但是由于我是先做完实验,再写的实验报告,所以实验过程中有很多图没截下来。这里只能提供一个大致思路理解了。

    实验步骤

    新建go项目以测试链接

    新建一个go项目,只需要有一个main.go即可。

    打开main.go。现在我们需要先试着访问数据库文件

    自己编写也可以,这里我选择用lab0中sqlite_ridership_db中的SQL来做测试。SQL语句很显眼,所以还是不难找的。

    先把SQL语句写好,其他的功能待会再补齐。

    1. package main
    2. import (
    3. _ "github.com/mattn/go-sqlite3"
    4. )
    5. func main() {
    6. query := `
    7. SELECT SUM(total_ons)
    8. FROM rail_ridership
    9. WHERE season = 'Fall 2017'
    10. AND time_period_id NOT IN ('time_period_10', 'time_period_11')
    11. AND line_id = ?
    12. GROUP BY time_period_id
    13. ORDER BY time_period_id;
    14. `
    15. }

    “github.com/mattn/go-sqlite3”这东西是一个数据库驱动的包,导入它之后就可以通过GO对sqlite数据库进行操作了。

    1. db, err := sql.Open("sqlite3", "建议使用数据库文件的绝对路径")
    2. if err != nil {
    3. log.Fatal(err)
    4. }
    5. defer db.Close()
    6. //要养成打开数据库后关闭链接的习惯

    此时你的main.go代码应该如下

    1. package main
    2. import (
    3. "database/sql"
    4. "fmt"
    5. "log"
    6. _ "github.com/mattn/go-sqlite3"
    7. )
    8. func main() {
    9. db, err := sql.Open("sqlite3", "c:/Users/LENOVO/Desktop/template/testgo/mbta.sqlite")
    10. if err != nil {
    11. log.Fatal(err)
    12. }
    13. defer db.Close()
    14. query := `
    15. SELECT SUM(total_ons)
    16. FROM rail_ridership
    17. WHERE season = 'Fall 2017'
    18. AND time_period_id NOT IN ('time_period_10', 'time_period_11')
    19. AND line_id = ?
    20. GROUP BY time_period_id
    21. ORDER BY time_period_id;
    22. `
    23. }

    接下来对db执行些操作才能知道到底有没有成功连接,我们先看看原本在lab0中这个SQL起什么作用。

    可以看到,在lab0中Query传入了两个参数。前者我我们要执行的SELECT查询SQL语句。后者则为一个string类型的字符串。

    而这个lineId会作为参数传入SQL语句中的”AND line_id =? “中,相当于是”AND line_id=lineId“.

    但我们测试总不能也直接用lineId,我们得自己指定lineId=xxxxx。不过这个lineId…没说明是什么,只知道它可能是xx线路的id。但是这个id到底是什么格式,没打注释。那只能翻翻代码看看是啥意思。我们先看看它的定义

    还是没说lineId是什么,但我们从这个函数大概能推断出:GetRidership( )接收string类型的 lineId,并返回一个int类型的切片和error。

    我们在文件中搜索lineId试试。此时在ridersihp_db_test中我们找到了lineIds

    还是没说它是干什么的,但我们知道了lineId应该和这四种颜色有关。我们推测lineId应该就是xxx地铁线路所代表的颜色。

    实验步骤

    navicat打开数据库文件mbta.sqlite

    为了验证lineId和颜色有关,我们查看一下数据库结构。这里使用navicat打开mbta.sqlite。

    看到有个lines,还有个rail_ridership,那么会不会lineId表示的是不同地铁线路所表示的颜色呢?但咱对波士顿也没什么了解,波士顿的地铁有几号线,不知道;xx号线用什么颜色表示,不知道。不过不知道也不重要,我们打开lines看看

    很明显了,line_id就应该表示的是xx号线,即“x号线的id”。

    写者注

    做这步只是为了更好的了解自己这次实验到底是在干什么,方便我们后面编写Handlers的具体函数。

    实验步骤

    补全测试代码

    那我们直接假设要查询“red line”这条线路的乘客量。那么把lab0中代码复制过来,再把lineId改成“red”试试,能获取到数据就说明连接是成功的。

    1. package main
    2. import (
    3. "database/sql"
    4. "fmt"
    5. "log"
    6. _ "github.com/mattn/go-sqlite3"
    7. )
    8. func main() {
    9. db, err := sql.Open("sqlite3", "c:/Users/LENOVO/Desktop/template/testgo/mbta.sqlite")
    10. if err != nil {
    11. log.Fatal(err)
    12. }
    13. defer db.Close()
    14. query := `
    15. SELECT SUM(total_ons)
    16. FROM rail_ridership
    17. WHERE season = 'Fall 2017'
    18. AND time_period_id NOT IN ('time_period_10', 'time_period_11')
    19. AND line_id = ?
    20. GROUP BY time_period_id
    21. ORDER BY time_period_id;
    22. `
    23. rows, err := db.Query(query, "green")
    24. defer rows.Close() //别忘了关闭连接
    25. fmt.Print(rows)
    26. }

    在fmt.Print(rows)那打个断点,方便我们查看变量的情况。调试一下,得到变量信息

    error为nil,说明连接过程没出现报错。rows也不为nil,说明rows确实获取到了数据库的数据。

    附录

    报错原因

    在Lab0“连接至数据库”前,你需要确保以下几点:

    • 你电脑有安装gcc,cmd输入gcc -v能显示版本信息。
      • 这是因为sqlite本身的源代码是c编写的。所以要和go一起用的话需要本地有c语言的编译环境。
    • mbta.sqlite有读写权限。
      • 由于mbta.sqlite这个文件是你自己下载下来的。如果你用的是linux,该文件很有可能默认没有读写权限,建议给mbta.sqlite所在的文件夹直接chmod加上权限。如果用的是windows,右键mbta.sqlite打开属性,你大概率会发现该文件提示已被锁定。解除锁定即可。
      • 对于windows,上面这个操作如果最后还是拿不到数据库的数据,cmd输入
        cacls c:/xxx/database /e /t /g everyone:F 。将数据库所在的文件夹设置为所有人可写。应该就能解决问题了。

    在测试用的main.go调试的时候,起码err必须是nil。rows之类的得根据你自己编写的SQL语句来看,如果是按Lab0给的实验代码,最后rows不能是nil。如果rows是nil的话只能根据error的信息自己慢慢查报错原因了。

    写者注

    多打断点多调试,理解代码后在几个go文件里找可能会出错的地方打上断点。我自己光是连接数据库这块打断点+调试就花了一个下午。

  • 相关阅读:
    『MySQL 实战 45 讲』17 - 如何正确地显示随机消息?(随机抽取 3 个词)
    二叉树和堆
    万字详解java接口
    PHP从多维数组中删除重复的值
    【Python零基础入门篇 · 36】:greenlet协程模块的使用、gevent模块的使用、程序打补丁、总结
    大数据1星笔试题_220621
    《最新出炉》系列入门篇-Python+Playwright自动化测试-46-鼠标滚轮操作
    GPIO子系统编写LED驱动
    时间序列预测 | Python实现Attention-Transformer时间序列预测(TSAT model)
    Java编码与解码
  • 原文地址:https://blog.csdn.net/white_night_SZTU/article/details/133883339