Golang中解决数据库初始化失败:因'CGO_ENABLED=0'导致go-sqlite3无法工作的错误

Golang中解决数据库初始化失败:因’CGO_ENABLED=0’导致go-sqlite3无法工作的错误 [错误] 初始化数据库失败,错误信息:二进制文件编译时设置了 ‘CGO_ENABLED=0’,go-sqlite3 需要 cgo 才能工作。这是一个存根。 2024/09/07 02:28:01 连接数据库失败:二进制文件编译时设置了 ‘CGO_ENABLED=0’,go-sqlite3 需要 cgo 才能工作。这是一个存根。 退出状态 1

后端

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/gorilla/mux"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
)

var db *gorm.DB

func main() {
	var err error
	// Open the SQLite database
	db, err = gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
	if err != nil {
		log.Fatalf("Failed to connect to the database: %v", err)
	}

	// Auto-migrate the User model
	err = db.AutoMigrate(&User{})
	if err != nil {
		log.Fatalf("Failed to migrate database schema: %v", err)
	}

	// Initialize the router
	r := mux.NewRouter()
	r.HandleFunc("/", HomeHandler)
	r.HandleFunc("/hello/{name:[a-zA-Z]+}", HelloHandler)
	r.HandleFunc("/users", CreateUserHandler).Methods("POST")

	// Start the server
	fmt.Println("Server starting on port 9999")
	log.Fatal(http.ListenAndServe(":9999", r))
}

type User struct {
	gorm.Model
	Name  string
	Email string
}

func HomeHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Welcome to the Home Page!")
}

func HelloHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	name := vars["name"]
	fmt.Fprintf(w, "Hello, %s!", name)
}

func CreateUserHandler(w http.ResponseWriter, r *http.Request) {
	// For demonstration purposes, handle user creation here
	// You might want to parse request body and insert user into the database

	// Example of creating a new user (make sure to parse JSON and validate input)
	var user User
	if err := r.ParseForm(); err != nil {
		http.Error(w, "Unable to parse form", http.StatusBadRequest)
		return
	}

	// Dummy data to demonstrate user creation
	user.Name = "John Doe"
	user.Email = "john@example.com"

	// Save user to the database
	if err := db.Create(&user).Error; err != nil {
		http.Error(w, "Failed to create user", http.StatusInternalServerError)
		return
	}

	fmt.Fprintf(w, "User created!")
}


更多关于Golang中解决数据库初始化失败:因'CGO_ENABLED=0'导致go-sqlite3无法工作的错误的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

使用 CGO_ENABLED=1 进行构建。

更多关于Golang中解决数据库初始化失败:因'CGO_ENABLED=0'导致go-sqlite3无法工作的错误的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


问题是什么?主题中没有说明。

错误信息很明确。你需要在构建时启用CGO,或者使用一个完全用Go编写、不依赖C语言绑定的驱动程序。

这个错误是因为使用了 gorm.io/driver/sqlite 包,它底层依赖 go-sqlite3 库,而该库需要 CGO 才能工作。当编译时设置了 CGO_ENABLED=0,就会导致这个存根错误。

有几种解决方案:

方案1:启用CGO编译

在编译时设置 CGO_ENABLED=1

# 设置环境变量
export CGO_ENABLED=1

# 然后编译
go build -o app main.go

或者在编译命令中直接指定:

CGO_ENABLED=1 go build -o app main.go

方案2:使用纯Go的SQLite驱动(推荐)

替换 gorm.io/driver/sqlite 为纯Go实现的SQLite驱动,比如 modernc.org/sqlite

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/gorilla/mux"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
	
	// 导入modernc.org/sqlite驱动
	_ "modernc.org/sqlite"
)

var db *gorm.DB

func main() {
	var err error
	// 使用modernc.org/sqlite作为驱动
	// 注意:这里需要使用自定义的dialector
	db, err = gorm.Open(sqlite.Dialector{
		DriverName: "sqlite",
		DSN:        "test.db",
	}, &gorm.Config{})
	
	if err != nil {
		log.Fatalf("Failed to connect to the database: %v", err)
	}

	// Auto-migrate the User model
	err = db.AutoMigrate(&User{})
	if err != nil {
		log.Fatalf("Failed to migrate database schema: %v", err)
	}

	// Initialize the router
	r := mux.NewRouter()
	r.HandleFunc("/", HomeHandler)
	r.HandleFunc("/hello/{name:[a-zA-Z]+}", HelloHandler)
	r.HandleFunc("/users", CreateUserHandler).Methods("POST")

	// Start the server
	fmt.Println("Server starting on port 9999")
	log.Fatal(http.ListenAndServe(":9999", r))
}

// ... 其他代码保持不变

同时更新 go.mod 文件:

go get modernc.org/sqlite

方案3:使用特定的GORM SQLite驱动

使用专门为无CGO环境设计的GORM SQLite驱动:

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/gorilla/mux"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
	
	// 使用gorm.io/driver/sqlite的纯Go版本
	sqliteDriver "github.com/glebarez/sqlite"
)

var db *gorm.DB

func main() {
	var err error
	// 使用纯Go的SQLite驱动
	db, err = gorm.Open(sqliteDriver.Open("test.db"), &gorm.Config{})
	
	if err != nil {
		log.Fatalf("Failed to connect to the database: %v", err)
	}

	// Auto-migrate the User model
	err = db.AutoMigrate(&User{})
	if err != nil {
		log.Fatalf("Failed to migrate database schema: %v", err)
	}

	// Initialize the router
	r := mux.NewRouter()
	r.HandleFunc("/", HomeHandler)
	r.HandleFunc("/hello/{name:[a-zA-Z]+}", HelloHandler)
	r.HandleFunc("/users", CreateUserHandler).Methods("POST")

	// Start the server
	fmt.Println("Server starting on port 9999")
	log.Fatal(http.ListenAndServe(":9999", r))
}

// ... 其他代码保持不变

安装对应的驱动:

go get github.com/glebarez/sqlite

方案4:使用database/sql标准库配合纯Go驱动

如果不依赖GORM,可以直接使用标准库:

package main

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

	"github.com/gorilla/mux"
	_ "modernc.org/sqlite"
)

var db *sql.DB

func main() {
	var err error
	// 直接使用database/sql和modernc.org/sqlite
	db, err = sql.Open("sqlite", "test.db")
	if err != nil {
		log.Fatalf("Failed to connect to the database: %v", err)
	}
	defer db.Close()

	// 创建表
	_, err = db.Exec(`
		CREATE TABLE IF NOT EXISTS users (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			name TEXT,
			email TEXT,
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP
		)
	`)
	if err != nil {
		log.Fatalf("Failed to create table: %v", err)
	}

	// Initialize the router
	r := mux.NewRouter()
	r.HandleFunc("/", HomeHandler)
	r.HandleFunc("/hello/{name:[a-zA-Z]+}", HelloHandler)
	r.HandleFunc("/users", CreateUserHandler).Methods("POST")

	// Start the server
	fmt.Println("Server starting on port 9999")
	log.Fatal(http.ListenAndServe(":9999", r))
}

type User struct {
	ID        int
	Name      string
	Email     string
	CreatedAt string
}

func HomeHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Welcome to the Home Page!")
}

func HelloHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	name := vars["name"]
	fmt.Fprintf(w, "Hello, %s!", name)
}

func CreateUserHandler(w http.ResponseWriter, r *http.Request) {
	if err := r.ParseForm(); err != nil {
		http.Error(w, "Unable to parse form", http.StatusBadRequest)
		return
	}

	// 插入用户数据
	_, err := db.Exec("INSERT INTO users (name, email) VALUES (?, ?)", 
		"John Doe", "john@example.com")
	
	if err != nil {
		http.Error(w, "Failed to create user", http.StatusInternalServerError)
		return
	}

	fmt.Fprintf(w, "User created!")
}

推荐使用方案2或方案3,它们允许你在保持GORM的同时,无需CGO即可编译和运行SQLite应用。

回到顶部