golang SQL和文档数据格式转换插件库sq的使用
Golang SQL和文档数据格式转换插件库sq的使用
概述
sq
是一个命令行工具,提供类似jq风格的访问结构化数据源的能力,包括SQL数据库和CSV/Excel等文档格式。它是sql+jq的结合体。
安装
macOS
brew install sq
Linux
/bin/sh -c "$(curl -fsSL https://sq.io/install.sh)"
Windows
scoop bucket add sq https://github.com/neilotoole/sq
scoop install sq
Go
go install github.com/neilotoole/sq
基本使用
添加数据源
# 下载示例数据库
wget https://sq.io/testdata/sakila.db
# 添加SQLite数据源
sq add ./sakila.db
@sakila sqlite3 sakila.db
# 列出数据源
sq ls -v
HANDLE ACTIVE DRIVER LOCATION OPTIONS
@sakila active sqlite3 sqlite3:///Users/demo/sakila.db
查询数据
# 使用jq风格查询
sq '.actor | .first_name, .last_name'
# 使用原生SQL查询
sq sql 'SELECT first_name, last_name FROM actor'
检查数据源结构
# 查看数据源结构
sq inspect
# 查看特定表结构
sq inspect .actor
完整示例
示例1:查询并导出CSV
# 查询actor表并导出为CSV
sq '.actor | .actor_id, .first_name, .last_name' --csv --output actors.csv
示例2:跨数据源连接
# 假设我们有一个CSV文件和一个PostgreSQL数据库
sq add ./employees.csv
sq add postgres://user:pass@localhost/mydb
# 执行跨源连接查询
sq '@csv.employees | join(@pg.employees, .id) | .name, .department'
示例3:使用Go代码调用sq库
package main
import (
"fmt"
"log"
"github.com/neilotoole/sq/libsq"
)
func main() {
// 创建sq实例
app := libsq.New()
// 添加数据源
err := app.AddSource("sakila", "sqlite3:///path/to/sakila.db")
if err != nil {
log.Fatal(err)
}
// 执行查询
result, err := app.Query("sakila", ".actor | .first_name, .last_name")
if err != nil {
log.Fatal(err)
}
// 输出结果
fmt.Println(result)
}
主要功能
- 数据查询:支持jq风格和原生SQL查询语法
- 数据转换:支持JSON、CSV、Excel等多种格式转换
- 跨源操作:可以在不同数据源之间进行连接查询
- 数据导入导出:支持将查询结果插入到其他数据库表
- 表操作:提供复制、截断和删除表的功能
输出格式
sq
支持多种输出格式:
--text
:文本格式--json
:JSON格式--csv
/--tsv
:CSV/TSV格式--xlsx
:Excel格式--html
:HTML格式--xml
:XML格式
总结
sq
是一个功能强大的数据操作工具,特别适合需要在不同数据格式和数据库之间进行转换和查询的场景。它结合了SQL的查询能力和jq的数据处理能力,为数据分析和处理提供了便捷的命令行界面。
更多关于golang SQL和文档数据格式转换插件库sq的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang SQL和文档数据格式转换插件库sq的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang SQL 和文档数据格式转换插件库 sq 的使用
sq 是一个强大的 Go 语言库,用于在 SQL 数据库和文档数据格式(如 JSON、XML 等)之间进行转换。它提供了简洁的 API 来处理数据库查询结果与结构化文档之间的映射。
安装 sq
go get github.com/bokwoon95/sq
基本用法
1. 从数据库查询转换为 JSON
package main
import (
"database/sql"
"encoding/json"
"fmt"
"log"
_ "github.com/lib/pq"
"github.com/bokwoon95/sq"
)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
IsActive bool `json:"is_active"`
}
func main() {
// 连接数据库
db, err := sql.Open("postgres", "user=postgres dbname=test sslmode=disable")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// 查询数据
rows, err := db.Query("SELECT id, name, email, is_active FROM users")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
// 使用 sq 将结果转换为 JSON
var users []User
err = sq.FetchAll(rows, &users)
if err != nil {
log.Fatal(err)
}
// 输出 JSON
jsonData, err := json.Marshal(users)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(jsonData))
}
2. 从 JSON 插入到数据库
func insertFromJSON(db *sql.DB) error {
jsonData := `[
{"name": "Alice", "email": "alice@example.com", "is_active": true},
{"name": "Bob", "email": "bob@example.com", "is_active": false}
]`
var users []User
err := json.Unmarshal([]byte(jsonData), &users)
if err != nil {
return err
}
// 使用 sq 批量插入
_, err = sq.Exec(db, sq.
InsertInto("users").
Columns("name", "email", "is_active").
Values(users...),
)
return err
}
高级特性
1. 自定义映射
type CustomUser struct {
UserID int `db:"id" json:"user_id"`
FullName string `db:"name" json:"full_name"`
// 其他字段...
}
func customMapping(db *sql.DB) {
rows, err := db.Query("SELECT id, name FROM users")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
var customUsers []CustomUser
err = sq.FetchAll(rows, &customUsers)
if err != nil {
log.Fatal(err)
}
// 输出自定义结构的JSON
jsonData, _ := json.Marshal(customUsers)
fmt.Println(string(jsonData))
}
2. 复杂查询构建
func complexQuery(db *sql.DB) {
// 构建复杂查询
query := sq.
Select("u.id", "u.name", "u.email", "COUNT(o.id) AS order_count").
From("users u").
LeftJoin("orders o", "o.user_id = u.id").
GroupBy("u.id", "u.name", "u.email").
Having("COUNT(o.id) > ?", 5).
OrderBy("order_count DESC")
// 执行查询
rows, err := query.Fetch(db)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
type UserWithOrders struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
OrderCount int `json:"order_count"`
}
var results []UserWithOrders
err = sq.FetchAll(rows, &results)
if err != nil {
log.Fatal(err)
}
jsonData, _ := json.Marshal(results)
fmt.Println(string(jsonData))
}
性能优化技巧
- 批量操作:使用 sq 的批量插入/更新功能提高性能
- 预编译语句:对频繁执行的查询使用预编译语句
- 流式处理:对于大数据集,使用流式处理避免内存溢出
func batchInsert(db *sql.DB, users []User) error {
_, err := sq.Exec(db, sq.
InsertInto("users").
Columns("name", "email", "is_active").
Values(users...),
)
return err
}
func streamProcessing(db *sql.DB) error {
rows, err := db.Query("SELECT * FROM large_table")
if err != nil {
return err
}
defer rows.Close()
var item struct {
ID int
Data string
}
for rows.Next() {
err := sq.Fetch(rows, &item)
if err != nil {
return err
}
// 处理每个项目而不是加载到内存
fmt.Println(item)
}
return nil
}
sq 库提供了强大而灵活的工具来处理 SQL 和文档数据格式之间的转换,通过合理使用可以大大简化数据持久层的工作。