himorogiの日記

主にプログラミングに関することなど。少々ハード(電子工作)についても。

【macOS】PowerShell から SQLite を使うための備忘録

前振り

現役時代 Windows 環境では PowerShell 活用し、業務では結構大量のデータを扱ってたために MS Access より SQLite を重宝してた。
定年リタイアで mac 専科に復帰したため、script は専ら Javascript でやろうと思ってたが、JXA は過疎ってるし node.js は逆に Version 管理面倒くさい…
とか思ってたら PowerShell core の登場で mac でも PowerShell が使えるように。

…が、リタイアしちゃったので、あんまり PowerShell 使う必要性に迫られない。
一応、pwsh を VSCode の terminal に常時立ち上げて shell として使ってるが、script 書くことは稀。

流石にこれではいかんと SQLite のハンドリングする PowerShell の script 書いてたら、どちらも暫く使ってないので結構忘れてた。
しかも今や老眼で、昔ならリファレンスやハンドブックを気軽に検索できたことが目が滑って全然頭に入らない。

というわけで、もっと老化(老眼や記憶力の低下)が進んだときに備え :-p) 基本の基本、あえて書くほどでもない極々当たり前の tips を、紙のメモだと見辛いのでここに記す。

sample データを準備する(csv

writeProverb2CSV.ps1

@"
1,厩戸皇子,以和爲貴
2,釈迦,天上天下唯我独尊
3,孔子,有朋自遠方来不亦楽乎
4,杜甫,国破山河在
"@ | ConvertFrom-CSV -header "ID","name","phrase" | Export-CSV Proverb.csv -NTI

いきなり script 出たけど、CSV ファイル構築するのに、Excel から引っ張ると妙な自動変換されることがあるし、text editor で編集するのは、" や ’ で item 毎に毎回文字列括るのが面倒。だからここでは here document で列挙し、それを一旦 ConvertForm-CSV に渡し、Export-CSV で書き出した。

Export-CSV の -NTI パラメータは PowerShell ver6 以降では要らないみたい…

以下は here document 使わない場合。

ConvertFrom-CSV(
    "1,厩戸皇子,以和爲貴",
    "2,釈迦,天上天下唯我独尊",
    "3,孔子,有朋自遠方来不亦楽乎",
    "4,杜甫,国破山河在"
) -header "ID","name","phrase" | Export-CSV Proverb.csv -NTI

その結果の Proverb.csv

"ID","name","phrase"
"1","厩戸皇子","以和爲貴"
"2","釈迦","天上天下唯我独尊"
"3","孔子","有朋自遠方来不亦楽乎"
"4","杜甫","国破山河在"

まぁ、実際にデータを準備するときは Google SpreadSheet などから直接 CSV 引っ張ってくると思う…

SQLite データベースファイルを作る

macOS だと、Windows 7 まで(Window 10 はあんまり知らない)のときみたいに encoding など default 設定弄る必要ないので、いきなり始められるのが嬉しい。
createProverb.ps1

sqlite3 ./myFirst.db "CREATE TABLE Proverb ( id, name, phrase );"
CSV から SQLite データベースファイルを初期化する

こういう query を渡したいけど面倒なので…

INSERT INTO Proverb ( id, name, phrase ) values( 1, '厩戸皇子', '以和爲貴' );
INSERT INTO Proverb ( id, name, phrase ) values( 2, '釈迦', '天上天下唯我独尊' );
INSERT INTO Proverb ( id, name, phrase ) values( 3, '孔子', '有朋自遠方来不亦楽乎' );
INSERT INTO Proverb ( id, name, phrase ) values( 4, '杜甫', '国破山河在' );

CSV から読み出して script で query 文字列生成して SQLite に渡す。

initProverbFromCSV.ps1

Import-CSV ./Proverb.csv | ForEach-Object{
    "INSERT INTO Proverb ( id, name, phrase ) values( $($_.ID), '$($_.name)', '$($_.phrase)' );"
} | sqlite3 ./myFirst.db $_

$($_.ID) と $() で括ってるのは文字列中に埋め込んでるから、正常に parse できるようにするため。

テーブルに正しく反映されたか確認

selectProverb.ps1

sqlite3 ./myFirst.db "SELECT * FROM Proverb;"

結果

PS /Users/hoge/handleProverb> ./selectProverb.ps1
1|厩戸皇子|以和爲貴
2|釈迦|天上天下唯我独尊
3|孔子|有朋自遠方来不亦楽乎
4|杜甫|国破山河在
PS /Users/hoge/handleProverb>
おまけ

敢えて書くほどのことでもないが…

deletProverb.ps1

sqlite3 ./myFirst.db "DELETE FROM Proverb;"