我创建了一个 SQL 文件,该文件加载到 sqlite3 中并为我创建了一堆表。在该 sql 文件中,我尝试使用 pragma 强制foreign_keys:
PRAGMA foreign_keys = on; -- also 1, true
Run Code Online (Sandbox Code Playgroud)
当我使用它加载 sql 文件时,-init它看起来不错:
$ sqlite3 -init sqlite3-empty.sql
-- Loading resources from sqlite3-empty.sql
SQLite version 3.22.0 2018-01-22 18:45:57
Enter ".help" for usage hints.
sqlite> pragma foreign_keys;
1
sqlite> .quit
Run Code Online (Sandbox Code Playgroud)
但是,如果我加载由上面的 sql 文件创建的数据库文件,它不会粘住:
$ sqlite3 unit_test.db
-- Loading resources from /home/me/.sqliterc
SQLite version 3.22.0 2018-01-22 18:45:57
Enter ".help" for usage hints.
sqlite> pragma foreign_keys;
foreign_keys
------------
0
sqlite> .quit
$ cat ~/.sqliterc
.headers …Run Code Online (Sandbox Code Playgroud) 在 go 中,我使用 mattn/go-sqlite3 模块打开 sqlite3 数据库。我使用 PRAGMAjournal_mode=WAL 打开后立即将数据库日志记录模式设置为 WAL。
但是,如果我在第一个进程运行时尝试从第二个进程打开数据库,第二个进程将无法打开它,而是会出现“数据库已锁定”错误。即使我没有执行任何交易,也会发生这种情况。
我使用的连接字符串是:
"file:mydbfile.db?cache=shared&mode=rwc"
Run Code Online (Sandbox Code Playgroud)
(我打算回答我自己的问题,因为调试花了很长时间)
我最近修改了我的应用程序,发现测试开始挂起。这是精简的测试代码:
package app_test
import (
"testing"
"github.com/kargirwar/prosql-go/db"
)
func TestApp(t *testing.T) {
db.SetDbPath("")
}
Run Code Online (Sandbox Code Playgroud)
db包如下:
package db
import (
"os"
"context"
"database/sql"
_ "github.com/mattn/go-sqlite3"
"path/filepath"
)
var dbPath string
func SetDbPath(path string) {
dbPath = path
}
func OpenDb(ctx context.Context, db string) (*sql.DB, error) {
db = filepath.Join(dbPath, db)
_, err := os.OpenFile(db, os.O_RDWR, 0600)
if err != nil {
return nil, err
}
return sql.Open("sqlite3", "file:"+db+"?_foreign_keys=true")
}
Run Code Online (Sandbox Code Playgroud)
我将问题追溯到这种依赖关系:
_ "github.com/mattn/go-sqlite3"
Run Code Online (Sandbox Code Playgroud)
如果我将其注释掉,那么测试就会正常运行,否则就会挂起。
奇怪的是, go run 工作得很好。Google 说 go-sqlite3 需要时间来编译,但是为什么 go …
这个问题与go-sqlite3 交叉编译 OSX 到 linux 的编译器参数相同,但由于这个问题没有答案,我会再次尝试询问。我有一个使用github.com/mattn/go-sqlite3 SQLite3 驱动程序的 Go 包,类似于以下内容:
package main
import (
_ "github.com/mattn/go-sqlite3"
)
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试在启用了 CGO 的情况下为 Linux AMD64 编译此文件(按照 SQLite3 的要求),我会收到以下错误:
> env GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go build
# github.com/mattn/go-sqlite3
sqlite3-binding.c:33123:42: error: use of undeclared identifier 'pread64'
sqlite3-binding.c:33141:42: error: use of undeclared identifier 'pwrite64'
sqlite3-binding.c:33274:22: error: invalid application of 'sizeof' to an incomplete type 'struct unix_syscall []'
sqlite3-binding.c:33283:22: error: invalid application of 'sizeof' to an incomplete type 'struct unix_syscall []'
sqlite3-binding.c:33310:20: error: invalid application …Run Code Online (Sandbox Code Playgroud)