Import

直接將 csv gzip 文件導入 SQLite 3

  • February 15, 2020

我想將一個 15GB 文件以逗號分隔的 gzip 壓縮文件導入 Sqlite 3,而不必使用臨時文件。

我想執行如下命令:

zcat input/surgical_code.csv.gz | tail -n +2 | sqlite3 db.sqlite ".import /dev/stdin surgical_code"

這會解壓縮文件,跳過標題並嘗試導入。

問題是我無法在同一個引用的命令上指定.mode cvsSQlite3 .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')

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

我發現 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

如果你執行man sqlite3,你可以找到命令行參數-csv-separator. 所以你可以做這樣的事情:

cat mycsvfile.csv | sqlite3 -csv -separator ';' mydb.db '.import /dev/stdin mycsvtable'

如果表不存在,SQLite 會自動創建表,使用第一行作為列名。我對此進行了測試,它就像一個魅力。這是將數據插入 SQLite 數據庫的最快方法之一,可與使用 pragma journal_mode=off 的準備好的插入語句相媲美。

如果您的 CSV 文件有超過 999 列,那麼您需要重新編譯 SQLite 並將 SQLITE_MAX_VARIABLE_NUMBER 從 999 更改為更高的數字。這是因為在內部,SQLite 使用受該限制約束的準備好的語句。

引用自:https://dba.stackexchange.com/questions/128520