Go操作DuckDB及使用Spatial

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
INSTALL spatial;
LOAD spatial;
CREATE TABLE world AS SELECT * FROM ST_Read('C:\Users\......\world.geojson');
SELECT * FROM world LIMIT 3;
┌─────────────────┬───────────┬───────────┬───┬──────────────────────┬──────────────────────┐
│   featurecla    │ scalerank │ labelrank │ … │       filename       │         geom         │
│     varchar     │   int32   │   int32   │   │       varchar        │       geometry       │
├─────────────────┼───────────┼───────────┼───┼──────────────────────┼──────────────────────┤
│ Admin-0 country │         05 │ … │ CRI.geojson          │ MULTIPOLYGON (((-8…  │
│ Admin-0 country │         05 │ … │ NIC.geojson          │ MULTIPOLYGON (((-8…  │
│ Admin-0 country │         36 │ … │ MAF.geojson          │ POLYGON ((-63.0175…  │
├─────────────────┴───────────┴───────────┴───┴──────────────────────┴──────────────────────┤
10 rows                                                             170 columns (5 shown)└───────────────────────────────────────────────────────────────────────────────────────────┘
SELECT name_zh FROM world WHERE ST_Contains(geom,ST_Point(92.5976562500021, 42.58220940617247));
┌────────────────┐
│    name_zh                       │
│    varchar                         │
├────────────────┤
│ 中华人民共和国               │
└────────────────┘

Go代码操作duckdb关键在于编译,直接导入写代码后编译会报错,至少windows下直接编译会报错。需按以下方法进行编译。 编译方法来自: https://github.com/marcboeker/go-duckdb/issues/115#issuecomment-1686384812

  1. 此处下载duckdb的Windows 动态链接库文件libduckdb-windows-amd64.zip
  2. 解压,假设解压到目录C:\Program Files\duckdb
  3. 将该目录添加到cgo编译标签路径中go env -w CGO_LDFLAGS="-LC:/Program Files/duckdb"(注意前面必须加-L,后面没有/
  4. 使用go build -tags=duckdb_use_lib main.go进行编译,并运行main.exe
  5. 或者将duckdb.dll放在项目目录,然后使用go run -tags=duckdb_use_lib main.go直接进行
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// Run with:
// CGO_LDFLAGS="-L<path to libduckdb_static.a>" 
// CGO_CFLAGS="-I<path to duckdb.h>" 
// DYLD_LIBRARY_PATH="<path to libduckdb.dylib>" 
// go run examples/test.go

package main

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

	_ "github.com/marcboeker/go-duckdb"
)

func main() {
	db, err := sql.Open("duckdb", "world.duckdb?access_mode=read_only")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	// 设置连接池参数
	db.SetMaxOpenConns(100)
	db.SetMaxIdleConns(100)

	db.Exec(`INSTALL 'spatial'; LOAD 'spatial';`)

	// 执行查询
	start := time.Now()
	res := db.QueryRow(`SELECT name_zh FROM world WHERE ST_Contains(geom,ST_Point(?,?))`, 92.5976562500021, 42.58220940617247)
	var name string
	res.Scan(&name)
	fmt.Println(name)
	fmt.Println(time.Since(start))
}