Changing the default SQLite driver for GORM

Publish: 2022-12-28 | Modify: 2022-12-28

Recently, I was developing a program and used GORM to operate on an SQLite database. GORM uses the gorm.io/driver/sqlite library as the default SQLite driver, which is implemented using CGO. I encountered some issues during the usage and eventually switched to a third-party SQLite driver to solve them.

Image

Issue

The problem I faced was due to the fact that the official GORM SQLite driver is implemented using CGO, which requires CGO support to work. I received the following error:

[error] failed to initialize database, got error Binary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo to work. This is a stub panic: Binary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo to work. This is a stub

This error message means that the GORM SQLite driver uses CGO and needs to be used in a CGO-enabled environment.

The solution to this problem is simple. You just need to modify the CGO_ENABLED environment variable to enable CGO support:

go env -w CGO_ENABLED=1

Enabling CGO will result in a dynamically linked binary. However, if you change the platform, such as running the program on Windows, it may fail to run due to missing dynamic libraries (e.g., SQLite). To ensure that the compiled binary can run without dynamic dependencies, static compilation needs to be considered. This creates a conflict with the GORM SQLite driver.

Solution: Switching to a Different SQLite Driver for GORM

I found someone else reporting a similar issue on the official GORM Issues page. Following that, I discovered the github.com/glebarez/sqlite library, which is implemented purely in Go and does not rely on CGO. The library can be found at: https://github.com/glebarez/sqlite

To switch from the official driver to this alternative driver, you need to replace the import statements:

import (
    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
)

with:

import (
    "github.com/glebarez/sqlite"
    "gorm.io/gorm"
)

This allows you to compile static binaries without CGO dependencies, thus solving the issue of dynamic library dependencies across different platforms.

Trade-offs

  • The glebarez/sqlite driver may have slightly lower performance compared to the official driver. However, sacrificing a small portion of performance for convenience is still worth it in my opinion. If you don't have cross-platform requirements, using the official default driver is sufficient.
  • The size of the statically compiled packaged file increases significantly.

Comments