直接将 csv gzip 文件导入 SQLite 3

pau*_*rry 6 sqlite import csv

我想将 15GB 文件逗号分隔的 gzip 压缩文件导入 Sqlite 3,而不必使用临时文件。

我想运行如下命令:

zcat input/surgical_code.csv.gz | tail -n +2 | sqlite3 db.sqlite ".import /dev/stdin surgical_code"
Run Code Online (Sandbox Code Playgroud)

这会解压缩文件,跳过标题并尝试导入。

问题是我无法在与 SQlite3 相同的引用命令上指定.mode cvs.separator ","

有任何想法吗?

使用$(echo -e 'line1\nline2')对我不起作用:

gzcat input/surgical_code.csv.gz | tail -n +2 | sqlite3 db.sqlite $(echo -e '.mode csv \n .separator \",\"\n.import /dev/stdin')
Run Code Online (Sandbox Code Playgroud)

Error: mode should be one of: ascii column csv html insert line list tabs tcl

小智 8

我发现 sqlite3 自定义初始化脚本可以有元命令以及 SQL 语句:

#!/bin/sh

commandfile=$(mktemp)

# create temporary init script
cat <<EOF > $commandfile
.mode csv tablename
.import /dev/stdin tablename
EOF

# import
bzip2 -d -c huge_compressed.csv.bz2 | sqlite3 --init $commandfile dbname.db
Run Code Online (Sandbox Code Playgroud)


hum*_*ads 7

如果运行man sqlite3,您可以找到命令行参数-csv-separator. 所以你可以做这样的事情:

cat mycsvfile.csv | sqlite3 -csv -separator ';' mydb.db '.import /dev/stdin mycsvtable'
Run Code Online (Sandbox Code Playgroud)

如果表不存在,SQLite 将自动创建该表,使用第一行作为列名。我测试了这个,它就像一个魅力。这是将数据插入 SQLite 数据库的最快方法之一,可与带有 pragma journal_mode=off 的准备好的插入语句相媲美。

如果您的 CSV 文件有超过 999 列,那么您需要重新编译 SQLite 并将 SQLITE_MAX_VARIABLE_NUMBER 从 999 更改为更高的数字。这是因为在内部,SQLite 使用受该限制约束的准备好的语句。