sqlite-lines
是一个 SQLite 扩展,用于从文件或 blob 中读取行。
更多信息请参见基准测试。
.load ./lines0
select line from lines_read('logs.txt');
当与 SQLite 的 JSON 支持结合使用时,sqlite-lines
对于面向行的数据集(如 ndjson 或 JSON Lines)非常有用。在这里,我们计算 Google 的 Quick, Draw! 数据集中针对 calendars.ndjson
的前 5 个国家/地区参与者。
select
line ->> '$.countrycode' as countrycode,
count(*)
from lines_read('./calendar.ndjson')
group by 1
order by 2 desc
limit 5;
/*
┌─────────────┬──────────┐
│ countrycode │ count(*) │
├─────────────┼──────────┤
│ US │ 141001 │
│ GB │ 22560 │
│ CA │ 11759 │
│ RU │ 9250 │
│ DE │ 8748 │
└─────────────┴──────────┘
*/
使用 SQLite CLI 的 fsdir()
表函数和 lines_read()
从目录中的每个文件中读取行。
select
name as file,
lines.rowid as line_number,
line
from fsdir('logs')
join lines_read(name) as lines
where name like '%.txt';
/*
┌─────────────────────┬──────┐
│ file │ line_number | line │
├───────┼─────────────┤──────┤
| a.txt | 1 | x |
| a.txt | 2 | y |
| a.txt | 3 | z |
| b.txt | 1 | xx |
| b.txt | 2 | yy |
| c.txt | 1 | xxx |
└───────┴─────────────┴──────┘
*/
完整的 API 参考和详细文档请参见 docs.md
。
语言 | 安装 | |
---|---|---|
Python | pip install sqlite-lines |
|
Datasette | datasette install datasette-sqlite-lines |
|
Node.js | npm install sqlite-lines |
|
Deno | deno.land/x/sqlite_lines |
|
Ruby | gem install sqlite-lines |
|
Github 发布版本 |
发布页面包含适用于 Linux amd64 和 MacOS (amd64, 无 arm) 的预构建二进制文件。
如果您想将 sqlite-lines
用作运行时可加载扩展,请从发布版本中下载 lines0.dylib
(适用于 MacOS) 或 lines0.so
文件,并将其加载到您的 SQLite 环境中。
注意:文件名中的
0
(lines0.dylib
或lines0.so
) 表示sqlite-lines
的主要版本。目前sqlite-lines
处于 v1 之前,因此未来版本可能会有重大变更。
例如,如果您正在使用 SQLite CLI,可以这样加载库
.load ./lines0
select lines_version();
-- v0.0.1
或者在 Python 中,使用内置的 sqlite3 模块
import sqlite3
con = sqlite3.connect(":memory:")
con.enable_load_extension(True)
con.load_extension("./lines0")
print(con.execute("select lines_version()").fetchone())
# ('v0.0.1',)
或者在 Node.js 中使用 better-sqlite3
const Database = require("better-sqlite3");
const db = new Database(":memory:");
db.loadExtension("./lines0");
console.log(db.prepare("select lines_version()").get());
// { 'lines_version()': 'v0.0.1' }
或者与 Datasette 一起使用(使用“无文件系统”版本来限制安全漏洞)
datasette data.db --load-extension ./lines_nofs0
Windows 尚不支持 - 尚未!
sqlite-lines
也作为一个独立的 SQL.js 库发布。它本质上是原始 SQL.js 库的一个分支,增加了 lines_version()
和 lines()
等 sqlite-lines
函数。
请查看此 Observable notebook 以获取完整演示。 发布页面包含 JavaScript 和 WASM 文件。
sqlite-lines
带有一个模仿 ndjson-cli 的示例 CLI,用于演示 sqlite-lines
的速度和多功能性。您可以从发布页面下载预编译版本,或者自己构建,使用
make cli
./dist/sqlite-lines
sqlite-lines
CLI 从标准输入读取数据,并通过其参数使用 SQL 代码应用转换。
第一个参数应该是用于转换来自标准输入的单行的 SQL 表达式。可用列包括 rowid
(正在处理的“行号”)和 d
(line
的别名,表示当前行的文本内容,灵感来自 ndjson-cli)。例如,要使用 upper()
将文件中的每一行转换为大写,使用
$ cat names.txt | sqlite-lines 'rowid || upper(d)'
1ALEX
2BRIAN
3CRAIG
这包括 SQLite 用于 NDJSON/JSONL 文件的新的 JSON ->
和 ->>
运算符
$ cat data.ndjson | sqlite-lines 'd ->> "$.id"'
$ cat data.ndjson | sqlite-lines 'json_object("name", d ->> "$.name", "age": d ->> "$.stats.age")'
第二个参数是另一个 SQL 表达式,用于底层 SQL 查询的 WHERE 语句中,以过滤掉行。
# get the names of all people older than 40
cat data.ndjson | sqlite-lines 'd ->> "$.name"' 'd ->> "$.age" > 40'
第三个参数是另一个 SQL 表达式,用于底层 SQL 查询的 GROUP BY 语句中,以聚合行。
sqlite-lines
对于 CSV 文件来说不是一个好的选择。技术上可行,但一旦您的数据在字段或标题中包含 \n
字符,您就会得到损坏的结果。