Databases 6 min read

How to Use SQLite3 in Go: A Step‑by‑Step Guide

This guide walks you through installing the Go SQLite3 driver, opening a database connection, creating tables, inserting records, querying data, and provides a complete runnable example, helping developers integrate lightweight SQLite storage into Go applications efficiently.

Ops Development & AI Practice
Ops Development & AI Practice
Ops Development & AI Practice
How to Use SQLite3 in Go: A Step‑by‑Step Guide

Introduction

SQLite is a lightweight embedded SQL engine; Go provides the database/sql package and the mattn/go-sqlite3 driver to work with SQLite. This article guides through setting up the environment, connecting to a SQLite file, and performing CRUD operations.

Environment preparation

Ensure Go is installed, then install the driver with go get -u github.com/mattn/go-sqlite3. Note that the driver uses cgo and requires a C compiler.

Opening a database

Import "database/sql" and the driver, then call sql.Open("sqlite3", "your_database.db"). If the file does not exist, SQLite creates it. Handle errors and defer db.Close().

Creating a table

Use db.Exec with a CREATE TABLE statement, for example:

createTableSQL := `CREATE TABLE IF NOT EXISTS projects (
    id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    name TEXT,
    description TEXT
);`
_, err = db.Exec(createTableSQL)
if err != nil { log.Fatal(err) }

Inserting data

Prepare an INSERT statement and execute it with parameters:

stmt, err := db.Prepare("INSERT INTO projects(name, description) VALUES(?, ?)")
if err != nil { log.Fatal(err) }
defer stmt.Close()
_, err = stmt.Exec("My Project", "This is a sample project")
if err != nil { log.Fatal(err) }

Querying data

Query rows and scan each record:

rows, err := db.Query("SELECT id, name, description FROM projects")
if err != nil { log.Fatal(err) }
defer rows.Close()
for rows.Next() {
    var id int
    var name, description string
    if err = rows.Scan(&id, &name, &description); err != nil { log.Fatal(err) }
    fmt.Println(id, name, description)
}
if err = rows.Err(); err != nil { log.Fatal(err) }

Full example

The complete program combines the steps above; see the code block below.

package main

import (
    "database/sql"
    "fmt"
    "log"
    _ "github.com/mattn/go-sqlite3"
)

func main() {
    db, err := sql.Open("sqlite3", "./test.db")
    if err != nil { log.Fatal(err) }
    defer db.Close()

    createTableSQL := `CREATE TABLE IF NOT EXISTS projects (
        id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
        name TEXT,
        description TEXT
    );`
    _, err = db.Exec(createTableSQL)
    if err != nil { log.Fatal(err) }

    stmt, err := db.Prepare("INSERT INTO projects(name, description) VALUES(?, ?)")
    if err != nil { log.Fatal(err) }
    defer stmt.Close()
    _, err = stmt.Exec("My Project", "This is a sample project")
    if err != nil { log.Fatal(err) }

    rows, err := db.Query("SELECT id, name, description FROM projects")
    if err != nil { log.Fatal(err) }
    defer rows.Close()
    for rows.Next() {
        var id int
        var name, description string
        if err = rows.Scan(&id, &name, &description); err != nil { log.Fatal(err) }
        fmt.Println(id, name, description)
    }
    if err = rows.Err(); err != nil { log.Fatal(err) }
}

Execution result

An example screenshot shows the printed row:

Conclusion

Using SQLite3 with Go provides a lightweight, efficient storage solution. The steps above enable basic CRUD operations, while real‑world projects should also consider error handling, transactions, and connection pooling to ensure robustness and performance.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

SQLdatabaseGoSQLiteTutorial
Ops Development & AI Practice
Written by

Ops Development & AI Practice

DevSecOps engineer sharing experiences and insights on AI, Web3, and Claude code development. Aims to help solve technical challenges, improve development efficiency, and grow through community interaction. Feel free to comment and discuss.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.