trdsql 1.2.3 配置参数详解

trdsql v1.2.3 两层配置体系逐参数实测:-help 全量回显与真实默认值、-driver/-dsn 三引擎(sqlite3/postgres/mysql)DSN 格式与写回库实测、config.json 命名连接(-db/-dblist/-config/-debug)行为与默认 db 切换对报错的影响、输入输出侧参数实测、生产配置模板与 5 条排障实录(Ubuntu 24.04.5 + PostgreSQL 16.15)

trdsqltrdsqlSQLCLI工具Go命令行2026/11/03

trdsql 1.2.3 配置参数详解

目标:逐参数讲清 trdsql v1.2.3 的两层配置体系——命令行 flag(全部选项与真实默认值,取自实测 -help 回显)与 config.json 命名连接文件(默认位置、字段、-db/-dblist 行为),并给出生产模板与排障实录,全部结论在 Ubuntu 24.04.5 + PostgreSQL 16.15 + SQLite 3.45.1 环境实测。

一、环境信息

  • 操作系统:Ubuntu 24.04.5 LTS(x86_64),主机名 trdsql-server,内网 10.89.56.2/24
  • trdsql:v1.2.3(/usr/local/bin/trdsql,官方二进制安装,见 《Ubuntu 24.04 安装 trdsql 1.2.3 指南》)
  • 查询引擎后端:内嵌 SQLite3(默认);PostgreSQL 16.15 数据库服务器 db-server(10.89.56.3,演示账号 root/q1w2e3r4,库 trdsql);SQLite 文件库 /opt/work/testdata/fruits.db、/opt/work/testdata/sales.db
  • 配置文件:/root/.config/trdsql/config.json(本文实测创建,样例见发布包 config.json.sample)
  • 测试数据:/opt/work/testdata/ 下 test.csv(无表头 3 行)、sales.csv(表头 id,name,price,city 共 8 行)

二、前置条件

trdsql 已安装且可执行:

$ trdsql -version
trdsql version v1.2.3

trdsql 没有强制配置文件——不创建任何 config.json 时以默认参数运行(内嵌 SQLite3 引擎、逗号分隔 CSV、内存临时库)。本文所有实测均基于该默认态起步,再叠加配置文件对比行为差异。

三、参数查看与修改方式

3.1 查看:-help 全量实测回显

$ trdsql -help
trdsql - Execute SQL queries on CSV, LTSV, JSON, YAML and TBLN.

Usage
	trdsql [OPTIONS] [SQL(SELECT...)]

Options:
  -A string           analyze the file but only suggest SQL.
  -a string           analyze the file and suggest SQL.
  -config string      configuration file location.
  -db string          specify db name of the setting.
  -dblist             display db information.
  -debug              debug print.
  -driver string      database driver.  [ mysql | postgres | sqlite3 | sqlite3_ext ]
  -dsn string         database driver specific data source name.
  -help               display usage information.
  -q string           read query from the specified file.
  -t string           read table name from the specified file.
  -version            display version information.

Input Formats:
  -icsv               CSV format for input.
  -ig                 guess format from extension. (default "true")
  -ijson              JSON format for input.
  -iltsv              LTSV format for input.
  -itbln              TBLN format for input.
  -itext              text format for input.
  -iwidth             width specification format for input.
  -iyaml              YAML format for input.

Input options:
  -id string          field delimiter for input. (default ",")
  -ih                 the first line is interpreted as column names(CSV only).
  -ijq string         jq expression string for input(JSON/JSONL only).
  -ilr int            limited number of rows to read. (default 0)
  -inull value        value(string) to convert to null on input.
  -inum               add row number column.
  -ir int             number of rows to preread. (default 1)
  -is int             skip header row. (default 0)

Output Formats:
  -oat                ASCII Table format for output.
  -ocsv               CSV format for output.
  -ojson              JSON format for output.
  -ojsonl             JSON lines format for output.
  -oltsv              LTSV format for output.
  -omd                Markdown format for output.
  -oraw               Raw format for output.
  -otbln              TBLN format for input.
  -otsv               TSV format for output.
  -ovf                Vertical format for output.
  -oyaml              YAML format for output.

Output options:
  -oaq                enclose all fields in quotes for output.
  -ocrlf              use CRLF for output. End each output line with '\r\n' instead of '\n'.
  -od string          field delimiter for output. (default ",")
  -oh                 output column name as header.
  -onowrap            do not wrap long lines(at/md only).
  -onull value        value(string) to convert from null on output.
  -oq string          quote character for output. (default "\"")
  -out string         output file name.
  -out-without-guess  output without guessing (when using -out).
  -oz string          output compression format. [ gz | bz2 | zstd | lz4 | xz ]

Examples:
  $ trdsql "SELECT c1,c2 FROM test.csv"
  $ trdsql -oltsv "SELECT c1,c2 FROM test.json::.items"
  $ cat test.csv | trdsql -icsv -oltsv "SELECT c1,c2 FROM -"

💡 说明:以上为 v1.2.3 实测输出原样照抄(-help 文本随版本演进,个别行如 -otbln 的描述措辞以官方二进制为准)。Go 的 flag 机制决定所有选项必须写在 SQL 参数之前——SQL 一旦开始,其后的内容整体视为查询语句(排障实录见第七章 FAQ Q1)。

3.2 修改:三层配置载体

载体位置/方式作用优先级
命令行 flagtrdsql [OPTIONS] SQL单次运行的全部行为最高
命名连接配置~/.config/trdsql/config.json 或 -config 文件预定义 driver/dsn 连接池,-db 名称 引用中(被 flag -driver/-dsn 覆盖)
环境变量仅影响构建/代理(GOPROXY 等,见安装篇)不参与运行时行为—

四、参数总览

按功能域分组(默认值均取自 3.1 实测 help 或本文实测行为):

组参数默认值一句话含义
引擎选择-driversqlite3SQL 执行引擎:mysql / postgres / sqlite3 / sqlite3_ext(CGO-free 版叫 sqlite)
引擎选择-dsn空(内存库)引擎的数据源串,格式随 driver(见 5.1)
引擎选择-config~/.config/trdsql/config.json命名连接配置文件位置
引擎选择-dbconfig 的 "db" 字段引用配置里的连接名
引擎选择-dblist—列出配置里的连接(名称:驱动)
输入格式-igtrue按扩展名猜格式(含自动解压 gz/bz2/zst/lz4/xz)
输入格式-icsv/-ijson/-iltsv/-iyaml/-itbln/-iwidth/-itext—显式指定输入格式
输入选项-ihfalse首行作列名(CSV 类)
输入选项-id","输入字段分隔符
输入选项-ijq空JSON/JSONL 的 jq 表达式取层级数据
输入选项-ilr0(不限)限制读入行数
输入选项-inull空(不转换)输入侧把指定串读成 SQL NULL
输入选项-inumfalse追加行号列
输入选项-ir1预读行数(探测列数/类型)
输入选项-is0跳过开头 N 行
输出格式-ocsv(默认)/-otsv/-ojson/-ojsonl/-oltsv/-oyaml/-otbln/-oat/-omd/-ovf/-oraw-ocsv结果转写格式
输出选项-outstdout输出文件名(按后缀猜格式,-out-without-guess 关闭猜测)
输出选项-oz空输出压缩:gz / bz2 / zstd / lz4 / xz
输出选项-ohfalse输出列名表头
输出选项-od / -oq / -oaq / -ocrlf"," / "\"" / false / falseCSV 类输出的分隔符/引号/全引号/CRLF
输出选项-onull""NULL 写出时替换成的字符串
输出选项-onowrapfalseat/md 输出不换行
辅助-a / -A—分析文件给建议 SQL / 只给 SQL
辅助-q—从文件读 SQL
辅助-t—整文件转换模式(读表名)
辅助-debugfalse打印配置加载、SQL 改写、类型猜测全过程

五、核心参数分类详解

5.1 引擎三件套:-driver / -dsn / -db

-driver 决定 SQL 在哪个引擎执行,-dsn 是引擎数据源串,两者是 trdsql 一切"高级能力"(方言、函数、写回数据库)的开关。各驱动 DSN 格式与实测:

sqlite3(默认)——DSN 即数据库文件路径;空 DSN 时用内存临时库,文件路径则直接在该库上执行(可读写已有 .db):

# 查询已有 SQLite 文件(表 fruits 由 sqlite3 CLI 预建)
$ trdsql -driver sqlite3 -dsn testdata/fruits.db "SELECT name, price FROM fruits WHERE price > 200 ORDER BY price DESC"
Orange,380
Apple,250

# 把 CSV 导出为全新 SQLite 库(建表导入)
$ rm -f testdata/sales.db
$ trdsql -ih -driver sqlite3 -dsn testdata/sales.db "CREATE TABLE sales AS SELECT * FROM testdata/sales.csv"

$ sqlite3 testdata/sales.db ".tables"; sqlite3 testdata/sales.db "SELECT COUNT(*) FROM sales;"
sales
8

postgres——DSN 为 libpq 关键字串(host= user= password= dbname= sslmode=):

$ trdsql -driver postgres -dsn "host=db-server user=root password=q1w2e3r4 dbname=trdsql sslmode=disable" "SELECT count(*) FROM testdata/sales.csv"
9

💡 说明:回显 9 是"表头行也被当作数据"的实测结果——未加 -ih 时 id,name,price,city 表头行按第 1 行数据装载(-ih 加上后为 8)。这正是 trdsql 最常见的计数偏差来源,详见 D1 篇。

mysql——DSN 为 go-sql-driver 格式 user:password@/dbname(本文环境无 MySQL 服务器,仅在配置文件中定义、未实测连接)。

写回目标库:CREATE TABLE ... AS SELECT 建表导入、INSERT INTO ... SELECT 追加导入,实测(PostgreSQL 16.15 服务器):

$ trdsql -driver postgres -dsn "host=db-server user=root password=q1w2e3r4 dbname=trdsql sslmode=disable" "CREATE TABLE fruits (id, name) AS SELECT c1::int, c2 FROM testdata/test.csv"

$ psql "host=db-server user=root password=q1w2e3r4 dbname=trdsql" -c "SELECT * FROM fruits;"
 id |  name
----+--------
  1 | Orange
  2 | Melon
  3 | Apple
(3 rows)
# 先建带类型的表,再用 INSERT INTO 导入(price 落 int 列;-db pdb 即 5.2 配置的 postgres 连接)
$ psql "host=db-server user=root password=q1w2e3r4 dbname=trdsql sslmode=disable" -c "CREATE TABLE sales(id int, name text, price int, city text);"
CREATE TABLE
$ trdsql -db pdb -ih "INSERT INTO sales SELECT id::int, name, price::int, city FROM testdata/sales.csv"
$ psql "host=db-server user=root password=q1w2e3r4 dbname=trdsql sslmode=disable" -c "SELECT city, sum(price) FROM sales GROUP BY city ORDER BY 2 DESC;"
   city    | sum
-----------+------
 Guangzhou | 1080
 Shanghai  | 1010
 Beijing   |  780
(3 rows)

-driver postgres 下临时表与库内表可直接 JOIN、可用窗口函数(实测见 D1 篇)。

5.2 config.json:命名连接文件

默认位置 ~/.config/trdsql/config.json(Unix 系),或 -config 显式指定。结构只有两个键(官方样例 config.json.sample 实测随发布包分发):

{
  "db": "pdb",
  "database": {
    "sdb": {
      "driver": "sqlite3",
      "dsn": "/opt/work/testdata/fruits.db"
    },
    "pdb": {
      "driver": "postgres",
      "dsn": "host=db-server user=root password=q1w2e3r4 dbname=trdsql sslmode=disable"
    },
    "ldb": {
      "driver": "sqlite3",
      "dsn": "/opt/work/testdata/sales.db"
    }
  }
}
  • "db":默认连接名——配置存在时,所有不带 -driver/-dsn/-db 的命令都用它执行(影响报错前缀,见 FAQ Q3);
  • "database":连接名 → {driver, dsn} 映射,数量不限。

-dblist 列出全部连接(名称:驱动,实测):

$ trdsql -dblist
pdb:postgres
ldb:sqlite3
sdb:sqlite3

💡 说明:实测两次 -dblist 输出顺序不同(另一轮为 sdb/pdb/ldb)——Go map 遍历无序,不要按顺序解析 -dblist 输出。

-db 名称 按名引用(实测三条分别走 postgres、sqlite 文件×2):

$ trdsql -db pdb "SELECT name FROM fruits ORDER BY id"
Orange
Melon
Apple

$ trdsql -db sdb "SELECT name, price FROM fruits WHERE price > 200"
Orange,380
Apple,250

$ trdsql -db ldb "SELECT city, SUM(CAST(price AS INT)) AS total FROM sales GROUP BY city"
Beijing,780
Guangzhou,1080
Shanghai,1010

注意 -db pdb 查 fruits 命中的是 PostgreSQL 里导入的表(5.1 建的那张),而 -db sdb 命中 SQLite 文件里的同名表——连接名即引擎路由。

-config 可用任意路径的配置文件(实测):

$ cp ~/.config/trdsql/config.json ./myconf.json
$ trdsql -config myconf.json -db sdb "SELECT * FROM fruits"
1,Orange,380
2,Melon,120
3,Apple,250

5.3 -debug:配置与执行过程透视

排障利器,实测完整链路(配置加载 → 连接选择 → SQL 改写 → 文件类型猜测 → 列名探测):

$ trdsql -debug -db pdb "SELECT count(*) FROM testdata/sales.csv" 2>&1 | head -8
2026/11/03 04:29:28 config found: /root/.config/trdsql/config.json
2026/11/03 04:29:28  [driver: sdb:sqlite3:/opt/work/testdata/fruits.db]
2026/11/03 04:29:28 >[driver: pdb:postgres:host=db-server user=root password=q1w2e3r4 dbname=trdsql sslmode=disable]
2026/11/03 04:29:28  [driver: ldb:sqlite3:/opt/work/testdata/sales.db]
2026/11/03 04:29:28 driver: postgres, dsn: host=db-server user=root password=q1w2e3r4 dbname=trdsql sslmode=disable
2026/11/03 04:29:28 [SELECT][ ][count][(][*][)][ ][FROM][ ][testdata/sales.csv]
2026/11/03 04:29:28 Guess file type as CSV: [testdata/sales.csv]
2026/11/03 04:29:28 Column Names: [c1,c2,c3,c4]

>[driver: ...] 行的 > 标出本次实际选用的连接;行首 2026/11/03 ... 为时间戳。

⚠️ 安全提示:-debug 会把 DSN 原文(含密码)打印到 stderr(实测回显如上,演示口令 q1w2e3r4)。生产环境开启 debug 的日志外发前务必脱敏,config.json 权限收紧(见第六章)。

5.4 输入侧参数实测

# -ih:首行作列名(对比 5.1 的 count=9 → 8)
$ trdsql -ih "SELECT city, count(*) AS cnt, sum(price) AS total FROM testdata/sales.csv GROUP BY city ORDER BY total DESC"
Guangzhou,2,1080
Shanghai,3,1010
Beijing,3,780

# -ilr 3:只读前 3 行数据
$ trdsql -ih -ilr 3 "SELECT * FROM testdata/sales.csv"
1,Orange,380,Beijing
2,Melon,120,Shanghai
3,Apple,250,Beijing

# -is 1:跳过第 1 行(表头行按数据跳掉,效果近似 -ih 但不建列名)
$ trdsql -is 1 "SELECT * FROM testdata/sales.csv" | head -3
1,Orange,380,Beijing
2,Melon,120,Shanghai
3,Apple,250,Beijing

# -id ":":自定义输入分隔符
$ printf "a:b\n1:2\n3:4\n" | trdsql -id ":" -ih "SELECT * FROM -"
1,2
3,4

# -inum:追加行号列
$ trdsql -inum "SELECT * FROM testdata/test.csv LIMIT 2"
1,1,Orange
2,2,Melon

# -ijq:JSON 层级取数
$ trdsql -ijson -ijq ".items" "SELECT * FROM -" < testdata/test.json
1,Orange,380
2,Melon,120
3,Apple,250

# -inull/-onull:NULL 语义
$ echo "1,,v" | trdsql -inull "" -onull "(NULL)" "SELECT * FROM -"
1,(NULL),v

5.5 输出侧参数实测

# -out 按后缀猜格式(json)
$ trdsql -ih -out out_sales.json "SELECT name,price FROM testdata/sales.csv LIMIT 2"
$ cat out_sales.json
[
  {
    "name": "Orange",
    "price": "380"
  },
  {
    "name": "Melon",
    "price": "120"
  }
]

# -oz 压缩输出(zstd,文件 26 字节)
$ trdsql -ih -out out_sales.csv.zst -oz zstd "SELECT name FROM testdata/sales.csv LIMIT 2"
$ ls -la out_sales.csv.zst
-rw-r--r-- 1 root root 26 Nov  3 04:34 out_sales.csv.zst

# -oh 输出表头 / -od 换分隔符 / -oaq 全字段引号
$ trdsql -otsv -oh "SELECT * FROM testdata/test.csv"
c1	c2
1	Orange
2	Melon
3	Apple
$ trdsql -ih -od ";" "SELECT name,city FROM testdata/sales.csv LIMIT 2"
Orange;Beijing
Melon;Shanghai
$ trdsql -ih -oaq "SELECT name,city FROM testdata/sales.csv LIMIT 2"
"Orange","Beijing"
"Melon","Shanghai"

# 表格类输出
$ trdsql -ih -omd "SELECT name,price FROM testdata/sales.csv LIMIT 3"
|  name  | price |
|--------|-------|
| Orange |   380 |
| Melon  |   120 |
| Apple  |   250 |

$ trdsql -ih -ovf "SELECT name,price FROM testdata/sales.csv WHERE city='Beijing' LIMIT 2"
---[ 1]------------------------
   name | Orange
  price | 380
---[ 2]------------------------
   name | Apple
  price | 250

六、生产配置模板

适用场景:运维跳板机/数据工位服务器(1–2 核、1GB 内存即可,trdsql 为一次性进程、无常驻资源占用),日常既查本地 SQLite 报表库、又查生产 PostgreSQL 分析库。

mkdir -p ~/.config/trdsql && cat > ~/.config/trdsql/config.json <<'EOF'
{
  "db": "local",
  "database": {
    "local": {
      "driver": "sqlite3",
      "dsn": "/opt/work/testdata/sales.db"
    },
    "pg-prod": {
      "driver": "postgres",
      "dsn": "host=db-server user=readonly password=q1w2e3r4 dbname=trdsql sslmode=require connect_timeout=5"
    },
    "pg-etl": {
      "driver": "postgres",
      "dsn": "host=db-server user=root password=q1w2e3r4 dbname=trdsql sslmode=require"
    }
  }
}
EOF
chmod 600 ~/.config/trdsql/config.json

逐项说明:

  • "db": "local":默认走本地 SQLite,误连生产的风险最低;需要生产引擎时显式 -db pg-prod;
  • pg-prod 用只读账号 + sslmode=require + connect_timeout=5(防挂死);pg-etl 才用可写账号跑 CREATE TABLE AS/INSERT INTO;
  • chmod 600:DSN 含口令,权限必须收紧(本文演示账号 root/q1w2e3r4 为测试口令;生产环境按敏感值规范用环境变量注入后渲染配置文件,不在文档/脚本落明文);
  • 读多写少的分析场景把 pg-prod 指向只读副本。

七、常见问题

Q1: 选项写在 SQL 后面不生效,还报语法错?

A: Go flag 机制:SQL 是位置参数,其后的内容不再按选项解析。实测把 -otsv 写到 SQL 后面:

$ trdsql "SELECT * FROM testdata/test.csv" -otsv
2026/11/03 04:35:27 export: near "-": syntax error [SELECT * FROM `testdata/test.csv` -otsv]

-otsv 被拼进了 SQL 语句。所有选项必须放在 SQL 之前:trdsql -otsv "SELECT * FROM testdata/test.csv"。

Q2: 配置里写了不存在的连接名?

A: 实测报错清晰、但不影响查询本身(stderr 提示后继续用默认引擎跑完):

$ echo '{"db": "nodb"}' > bad.json
$ trdsql -config bad.json "SELECT 1"
2026/11/03 04:29:28 ERROR: db[nodb] does not found
1

Q3: 创建 config.json 后,同样的错误信息变了(pq: 前缀)?

A: 因为 "db": "pdb" 把默认引擎从内嵌 SQLite3 切到了 PostgreSQL,SQL 错误改由 PostgreSQL 抛出。实测同一句不存在的表查询:

# 无配置(默认 sqlite3)
$ trdsql "SELECT c1 FROM nonexistent.csv"
2026/11/03 04:35:27 export: no such table: nonexistent.csv [SELECT c1 FROM nonexistent.csv]

# 有配置 db=pdb(postgres 引擎)
$ trdsql -db pdb -ih "SELECT name, price FROM fruits WHERE id > 1"
2026/11/03 04:29:28 export: pq: column "price" does not exist at column 14 (42703) [SELECT name, price FROM fruits WHERE id > 1]

第二条是真实列引用错误:PostgreSQL 里的 fruits 表只有 (id, name) 两列(5.1 导入时建的),没有 price——pq: ... (42703) 即 PG 的 42703 错误码原样透传。看到 pq:/mysql 风格报错,先检查 config.json 的默认 db 是否生效。

Q4: -help 里 -driver 的取值列表和 README 不一致?

A: v1.2.3 实测 help 显示 [ mysql | postgres | sqlite3 | sqlite3_ext ];README §3.1 写 [ mysql | postgres | sqlite3 | sqlite(CGO Free) ]。sqlite3_ext/sqlite 均为 CGO-free 变体(README §1.6),以所用版本的 -help 为准。

Q5: 数值列排序/比较结果"不对"?

A: 配置层面的根因是没有类型声明入口——trdsql 把文本列全部按 text 装载(-a 实测 Data types 全为 text),ORDER BY price 走字典序。解法在 SQL 侧显式转换:SQLite 用 CAST(price AS INTEGER)、PostgreSQL 用 price::int(实测对照见 D1 篇)。

八、参考链接