himorogiの日記

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

【macOS】PowerShell から SQLite を使うための備忘録・補遺【.import】

これは 2021 年 12 月 1 日の以下の記事の補足・補遺です。

macOSPowerShell から SQLite を使うための備忘録【.import】 - himorogiの日記himorogi.hatenablog.com

尚、前回、myFirst.db としてたところは、今回 Proverb.db にリネームしている。

さて、前回 .import の実例として以下のソースを掲示した。

importProverb.ps1

@"
CREATE TABLE Proverb ( id, name, phrase );
.separator ,
.import ./Proverb.csv Proverb
SELECT * FROM Proverb;
"@ | sqlite3 ./Proverb.db $_

上のコードは、テーブルの生成・セパレータの変更・インポート実行を一気に行なっている。
ps1 ファイルに記述して、外部コマンドとして実行している。

前回にも指摘したが、留意すべき点として… .import する CSV ファイルにヘッダーを含むと .import はそのままでは先頭行もデータと見做してしまう。

実は、.import には複数のオプションがあり、--skip N (N は任意の数、読み飛ばす行数を指定)で、ヘッダーを読み飛ばすことができる。
SQLite は長年簡易なポケットリファレンスを見ながら決め打ちで使ってたため(このような場面で usege が出てくることもなく)、--skip オプションがあることに気が付かなかった。

従って、前回やったように、別途 CSV ファイルからヘッダーを削除した中間ファイルを作成する必要はない。

この場合、.import の行は以下のように記述すれば、CSV ファイル先頭行のヘッダーを無視できる。

.import ./Proverb.csv --skip 1 Proverb

また SQLite では、セパレータにはデフォルトで '|' が使われており、冒頭のソースコードは .separator コマンドで、CSV ファイルのまま読み込めるようセパレータを変更している。

.import コマンドには、--skip N 以外にもオプションがあってインポートするファイルの形式を色々指定でき、--csv を指定すれば、.separator を使わずとも CSV ファイルのまま読み込める。
今回は .ps1 ファイルを作成せず REPL から直接実行してみた。

尚、前回インポートしたデータが残ってるので、最初に DELETE を実行している。

PS /Users/hoge/devPwsh> @"
>> DELETE FROM Proverb;
>> .import ./Proverb.csv --csv --skip 1 Proverb
>> SELECT * FROM Proverb;
>> "@ | sqlite3 ./Proverb.db $_
1|厩戸皇子|以和爲貴
2|釈迦|天上天下唯我独尊
3|孔子|有朋自遠方来不亦楽乎
4|杜甫|国破山河在
PS /Users/hoge/devPwsh> 

.separator によるセパレータの変更は、セッション中は有効なので、ヒアドキュメントにより複文を実行した際は SELECT 文の結果も CSV の体裁になっていたが、--csv オプションによる CSV インポートでは、CSV を内部形式に変換するのみ(※ 2022/07/04 注:というより .import ステートメント中のみ有効)なので、ヒアドキュメント中の直後に実行した SELECT 文の結果でも CSV の体裁にはならない。

PowershellSQLite の間で、データを CSV 形式でやり取りするなら、.import やSQL文実行の都度 .separator を記述する必要がある。
ただ、自分的には、モーダルな .separator を毎回実行するより、以下の方が機能的に明解なので、こちらでやろうと思う。

ここでも前回インポートしたデータを消すために最初に DELETE を実行している。

PS /Users/hoge/devPwsh> @"
>> DELETE FROM Proverb;
>> .import ./Proverb.csv --csv --skip 1 Proverb
>> SELECT * FROM Proverb;
>> "@ | sqlite3 ./Proverb.db $_ | convertfrom-csv -delimiter '|' | convertto-csv 
"1","厩戸皇子","以和爲貴"
"2","釈迦","天上天下唯我独尊"
"3","孔子","有朋自遠方来不亦楽乎"
"4","杜甫","国破山河在"
PS /Users/hoge/devPwsh> 

一見煩雑だけど Powershell に直接読み取る場合は、convertto-csv 不要だし、convertfrom-csvPOSIX 経由で SQLite とやり取りする限り必要なので

  • .separator の代わりに .import で --csv オプションを使う
  • .separator の代わりに convertfrom-csv で -delimiter '|' を指定する

だけなら、結果的に手間は同じ。