【问题标题】:How to read a SQLite database using GORM one row at a time如何一次使用 GORM 读取 SQLite 数据库一行
【发布时间】:2018-08-24 07:27:06
【问题描述】:

我有以下代码

package main

import (
    "database/sql"
    "fmt"
    "log"

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

func getDatabaseHandle(dbpath string) (*sql.DB, error) {
    database, err := sql.Open("sqlite3", dbpath)
    if err != nil {
        log.Printf("Failed to create the handle")
        return nil, err
    }
    if err = database.Ping(); err != nil {
        fmt.Printf("Failed to keep connection alive")
        return nil, err
    }
    return database, nil
}

func getAllRows(database *sql.DB, table string) {
    query := fmt.Sprintf("SELECT User, AppName FROM %s LIMIT 10", table)
    rows, err := database.Query(query)
    if err != nil {
        panic(err)
    }
    defer rows.Close()
    for rows.Next() {
        var id int
        var app string
        rows.Scan(&id, &app)
        fmt.Println(id, app)
    }
}

func main() {
    db, err := getDatabaseHandle("./gozo.db")
    if err != nil {
        panic(err)
    }
    defer db.Close()
    getAllRows(db, "timesheet")
}

这是针对具有以下列的 SQLite 数据库

id, User, Matter, AppName, AppDesc, Duration, Type, Timestamp

上面的码字完美。但是有两个问题

  1. 我需要为我打算在执行 for rows.Next() 的 for 循环中使用的每个列声明变量,这很烦人并且不能轻易模块化。

  2. 我需要使用 ORM 工具来实现数据库可移植性等等。

因此我绑定了GORM,这是我的代码

type Timesheet struct {
    id        int
    User      int
    Matter    int
    AppName   string
    AppDesc   string
    Duration  int64
    Type      string
    Timestamp string
}

// TableName -- Sets the table name
func (ts Timesheet) TableName() string {
    return "timesheet"
}

func main() {
    db, err := gorm.Open("sqlite3", "./gozo.db")
    if err != nil {
        panic(err)
    }
    defer db.Close()
    var ts []Timesheet
    db.Find(&ts).Limit(5)
    fmt.Println(ts)
}

但这并没有正确地给我数据,而是给了我所有的值 0。此外,这不是使用每个行扫描迭代,因此我可以在执行一些其他相关操作时包装这个 go 并发。这似乎在提取所有数据,这也是错误的。请告诉我如何在循环中扫描每一行并使用 GORM 获取正确的数据。

【问题讨论】:

  • 该结构看起来不太正确,您缺少 gorm 结构标签。还有gorm Models..doc.gorm.io/models.html,也是您关于一次获取一行的最初问题..您需要for循环,限制为1和一个偏移计数器
  • 第二个问题我找到了答案,但第一个问题我看不出我的结构有什么问题。

标签: go go-gorm


【解决方案1】:

我找到了答案。 GORM 文档并没有那么冗长,但流动性可能就是答案。

package main

import (
    "fmt"

    "github.com/jinzhu/gorm"
    _ "github.com/jinzhu/gorm/dialects/sqlite"
)

// Product -- Represents a product
type Product struct {
    gorm.Model
    Code  string
    Price uint
}

// TableName setting the table name
func (Product) TableName() string {
    return "allProducts"
}

func main() {
    db, err := gorm.Open("sqlite3", "test.db")
    if err != nil {
        panic("failed to connect database")
    }
    defer db.Close()
    var product Product
    rows, err := db.Model(&Product{}).Rows()
    defer rows.Close()
    if err != nil {
        panic(err)
    }
    for rows.Next() {
        db.ScanRows(rows, &product)
        fmt.Println(product)
    }
}

【讨论】:

    猜你喜欢
    • 2010-09-05
    • 2011-09-17
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多