私は厳密に純粋なCSV形式で結果をstdoutに出力するプログラムを書いています。 (各行はレコードを表し、同じカンマ区切りのフィールドセットを含み、フィールドには小文字の英語の文字、数字、およびドットのみが含まれ、スペースはなく、引用符もありません。エスケープ/エンコードする必要がある記号はありません。
この出力を完全にフィットするSQLiteテーブルにどのようにリダイレクトできますか?
制約に違反するか(たとえば、すでにテーブルにあるレコードと同じプライマリ/セカンダリキーを持つ)、既存のレコードを置き換えるか自動的に削除するかを制御できればよいでしょう。
もちろん、プログラム自体に直接SQLiteデータベース出力サポートを構築することもできますが、可能であればUNIXアプローチを好みます。
答え1
それでも使用するより簡単な解決策を見つけました。sqlite3
.import
ただし、これは読み取りまたは一時的に名前付きパイプを読み取りません/dev/stdin
。むしろこれと.import
関連がある。パイプラインオペレータ呼び出しはcat -
標準入力から直接読み取られます。
#!/bin/bash
function csv_to_sqlite() {
local database_file_name="$1"
local table_name="$2"
sqlite3 -csv $database_file_name ".import '|cat -' $table_name"
}
database_file_name=$1
table_name=$2
csv_to_sqlite "$database_file_name" "$table_name"
これは、Windowsコマンドシェルでは機能しません。
答え2
2つの方法:
サンプルtest.csv
ファイル:
GroupName,Groupcode,GroupOwner,GroupCategoryID
System Administrators,sysadmin,13456,100
Independence High Teachers,HS Teachers,,101
John Glenn Middle Teachers,MS Teachers,13458,102
Liberty Elementary Teachers,Elem Teachers,13559,103
1st Grade Teachers,1stgrade,,104
2nd Grade Teachers,2nsgrade,13561,105
3rd Grade Teachers,3rdgrade,13562,106
Guidance Department,guidance,,107
1)とcsvkit(CSV変換および操作用のコマンドラインツールセット)
輸入するSQLite3データベース:
csvsql --db sqlite:///test_db --tables test_tbl --insert test.csv
入力csvファイルが指定されていない場合、stdinはcsvデータを受け入れます。
... | csvsql --db sqlite:///test_db --tables test_tbl --insert
データ抽出SQLiteデータベース:
sql2csv --db sqlite:///test_db --query 'select * from test_tbl limit 3'
出力:
GroupName,Groupcode,GroupOwner,GroupCategoryID
System Administrators,sysadmin,13456,100
Independence High Teachers,HS Teachers,,101
John Glenn Middle Teachers,MS Teachers,13458,102
2)とSQLite3コマンドラインツール(ユーザーはSQL文を手動で入力して実行できます)SQLiteデータベース)
"
.import
"コマンドを使用して、CSV(カンマ区切り値)データをSQLiteテーブルにインポートします。 ".import
"コマンドには、2つのパラメータ、つまりCSVデータを読み取るディスクファイル名と、CSVデータを挿入するSQLiteテーブル名があります。コマンドを実行する前に、モードをcsvに設定することが重要です
.import
。これは、コマンドラインシェルが入力ファイルのテキストを別の形式に解釈するのを防ぐために必要です。
$ sqlite3
sqlite> .mode csv
sqlite> .import test.csv test_tbl
sqlite> select GroupName,Groupcode from test_tbl limit 5;
"System Administrators",sysadmin
"Independence High Teachers","HS Teachers"
"John Glenn Middle Teachers","MS Teachers"
"Liberty Elementary Teachers","Elem Teachers"
"1st Grade Teachers",1stgrade
sqlite>
答え3
Unixシリーズシステムではsqlite3
注文する.import
CSVの内容は特殊ファイルの標準入力から読み取ることができます/dev/stdin
。
$ printf "col1,col2\na,1\nb,2\n" | sqlite3 test.db ".import --csv /dev/stdin test"
$ sqlite3 -csv -header test.db "SELECT * FROM test"
col1,col2
a,1
$ sqlite3 -version
3.32.3 2020-06-18 14:00:33 7ebdfa80be8e8e73324b8d66b3460222eb74c7e9dfd655b48d6ca7e1933cc8fd
b,2
答え4
次のbash関数はcsv_to_sqlite
標準入力からCSVコンテンツを読み取り、次のコマンドを使用してSQLiteデータベーステーブルにインポートします。sqlite3
注文する.import
一時的な名前付きパイプ(FIFO):
#!/bin/bash
function csv_to_sqlite() {
local database_file_name="$1"
local table_name="$2"
local temp_input_fifo=$(mktemp -u)
mkfifo $temp_input_fifo
sqlite3 -csv $database_file_name ".import $temp_input_fifo $table_name" &
cat > $temp_input_fifo
rm $temp_input_fifo
}
database_file_name=$1
table_name=$2
csv_to_sqlite "$database_file_name" "$table_name"
$ printf "col1,col2,col3\na,1,2.6\nb,2,5.4\n" | ./csv_to_sqlite test.sqlite test
$ sqlite3 -csv -header test.sqlite "SELECT * FROM test"
col1,col2,col3
a,1,2.6
b,2,5.4