sqlite3のコマンドラインインターフェース(CLI)操作は、sqlite3.exeの引数としたものと、ドットコマンドによるものとがあり ます。操作については、その3や、それ以降の章の中で、説明しております。もう少し、実務に役立ちそうなコマンドについて取り上げてみたいと思います。
ここでは、region.sq3というデータベースとmy_db.sq3というデータベースについて操作題材としてとりあげてみることにします。 region.sq3の中には、地域をコード化したkanto_regionテーブルがあり、my_db.sq3では、my_friendテーブルが前者 を利用とするテーブル間の構図を想定しております。
sqlite3の起動
takai@takai-pc ~/db
$ mkdir command_basic
takai@takai-pc ~/db
$ cd command_basic/
sqlite3.exe に引数を何もつけない場合
データベースをメモリー内で保存・操作します。
.shell CMD ARGS... Run CMD ARGS... in a system shell
シェルコマンドを実行する。
.save FILE Write in-memory database into FILE
インメモリーデータベースを指定ファイルに書き出す。
.open ?OPTIONS? ?FILE? Close existing database and reopen FILE
カレントデータベースを閉じて、指定ファイルをオープンする。
Options:
--append Use appendvfs to append database to the end of FILE
--new Initialize FILE to an empty database
--nofollow Do not follow symbolic links
--readonly Open FILE readonly
--zip FILE is a ZIP archive
$ sqlite3
SQLite version 3.34.0 2020-12-01 16:14:00
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
-- データベースを保持するために新しい一時ファイルが作成されます
-- 作成した接続が終了すると自動的に削除されます。
sqlite> .databases
main: "" r/w
sqlite> create table new1 (
...> id integer primary key not null,
...> name text not null
...> );
sqlite> .tables
new1
sqlite> .shell ls -la
合計 8
drwxr-xr-x 1 takai None 0 12月 12 15:12 .
drwxr-xr-x 1 takai None 0 12月 12 14:51 ..
-- メモリ内のページャ キャッシュに常駐し、動作する為、ディスクには作成されていない
sqlite> insert into new1 values (
...> null, 'takai'
...> );
sqlite> insert into new1 values (
...> null, 'kato'
...> );
sqlite> insert into new1 values (
...> null, 'yamada'
...> );
sqlite> select * from new1;
1|takai
2|kato
3|yamada
-- saveドットコマンドでin-memoryで作成したデータベースをディスクに保存できる
sqlite> .save new1_db.sq3
sqlite> .shell ls -la
合計 16
drwxr-xr-x 1 takai None 0 12月 12 15:23 .
drwxr-xr-x 1 takai None 0 12月 12 14:51 ..
-rwxr-xr-x 1 takai None 8192 12月 12 15:23 new1_db.sq3
-- openドットコマンドで開ける
sqlite> .open new1_db.sq3
sqlite> .databases
main: /home/takai/db/command_basic/new1_db.sq3 r/w
sqlite> .quit
sqlite3.exe の引数にデータベース名を指定する
データベースファイル名を指定するとデータベースファイルが読み出される。データベースファイルが存在しない場合は新規に作成される。
takai@takai-pc ~/db/command_basic
$ sqlite3 new2_db.sq3
SQLite version 3.34.0 2020-12-01 16:14:00
Enter ".help" for usage hints.
sqlite> .databases
main: /home/takai/db/command_basic/new2_db.sq3 r/w
-- プライマリーデータベースとしてデータベースが作成されている
sqlite> create table new2 (
...> id integer primary key not null,
...> name2 text not null
...> );
sqlite> .shell ls -la
合計 32
drwxr-xr-x 1 takai None 0 12月 12 18:09 .
drwxr-xr-x 1 takai None 0 12月 12 14:51 ..
-rwxr-xr-x 1 takai None 8192 12月 12 15:23 new1_db.sq3
-rwxr-xr-x 1 takai None 8192 12月 12 18:09 new2_db.sq3 -- 新規作成
-- カレントディレクトリにデータベースファイルとして作成されている
sqlite> insert into new2 values (
...> null, 'takai2'
...> );
sqlite> insert into new2 values (
...> null, 'kato2'
...> );
sqlite> insert into new2 values (
...> null, 'yamada2'
...> );
sqlite> select * from new2;
1|takai2
2|kato2
3|yamada2
sqlite> .quit
takai@takai-pc ~/db/command_basic
$ ls -la
合計 24
drwxr-xr-x 1 takai None 0 12月 12 18:12 .
drwxr-xr-x 1 takai None 0 12月 12 14:51 ..
-rwxr-xr-x 1 takai None 8192 12月 12 15:23 new1_db.sq3
-rwxr-xr-x 1 takai None 8192 12月 12 18:12 new2_db.sq3
-- コマンドプロンプトを閉じてもファイルが残る
sqlite3.exe を インメモリーで開く
データベースをメモリー内で保存・操作します。
takai@takai-pc ~/db/command_basic
$ sqlite3 ":memory:"
SQLite version 3.34.0 2020-12-01 16:14:00
Enter ".help" for usage hints.
sqlite> .databases
main: "" r/w
sqlite> create table new3 (
...> id integer primary key not null,
...> name text not null
...> );
sqlite> .tables
new3
sqlite> .shell ls -la
合計 24
drwxr-xr-x 1 takai None 0 12月 12 18:12 .
drwxr-xr-x 1 takai None 0 12月 12 14:51 ..
-rwxr-xr-x 1 takai None 8192 12月 12 15:23 new1_db.sq3
-rwxr-xr-x 1 takai None 8192 12月 12 18:12 new2_db.sq3
sqlite> insert into new3 values (
...> null, 'takai3'
...> );
sqlite> insert into new3 values (
...> null, 'kato3'
...> );
sqlite> insert into new3 values (
...> null, 'yamada3'
...> );
sqlite> select * from new3;
1|takai3
2|kato3
3|yamada3
sqlite> .save new3_db.sq3
sqlite> .shell ls -la
合計 32
drwxr-xr-x 1 takai None 0 12月 12 18:30 .
drwxr-xr-x 1 takai None 0 12月 12 14:51 ..
-rwxr-xr-x 1 takai None 8192 12月 12 15:23 new1_db.sq3
-rwxr-xr-x 1 takai None 8192 12月 12 18:12 new2_db.sq3
-rwxr-xr-x 1 takai None 8192 12月 12 18:30 new3_db.sq3 -- 新規作成
sqlite> .databases
main: "" r/w -- .save filename 実行後はデータベース情報はクリアーされる
sqlite> .open new3_db.sq3
sqlite> .databases
main: /home/takai/db/command_basic/new3_db.sq3 r/w
sqlite> .quit
-- 以上、引数を何もつけない場合と同じ動作である。
-- 違いは、メモリー内だけにテータベースが存在する。(一時データベースの場合では、ディスクにスワップされる事がある)
複数のデータベースファイルを操作する
ATTACH DATABASE 'DatabaseName' As 'Alias-Name';
ATTACH 複数のデータベースを利用する場合、使用するデータベースを選択する
存在しないDatabaseName の場合は、作成される
DETACH DATABASE 'Alias-Name';
データベースの接続を切断する
region.sq3 データベースファイルを作成する
takai@takai-pc ~/db/command_basic
$ cd ..
takai@takai-pc ~/db
$ mkdir attach_sample
takai@takai-pc ~/db
$ cd attach_sample
---- region.sq3データベースを作成
takai@takai-pc ~/db/attach_sample
$ sqlite3 region.sq3 -- region.sq3 データベース名
SQLite version 3.34.0 2020-12-01 16:14:00
Enter ".help" for usage hints.
sqlite> .databases
main: /home/takai/db/attach_sample/region.sq3 r/w
---- kanto_region テーブルを作成
sqlite> create table kanto_region (
...> code integer primary key not null,
...> name text not null
...> );
---- データを挿入する
sqlite> insert into kanto_region values(101, 'tokyo');
sqlite> insert into kanto_region values(null, 'kanagawa');
sqlite> insert into kanto_region values(null, 'saitama');
sqlite> insert into kanto_region values(null, 'tiba');
sqlite> insert into kanto_region values(null, 'ibaragi');
sqlite> insert into kanto_region values(null, 'totigi');
sqlite> insert into kanto_region values(null, 'gunma');
---- 挿入されているテーブルレコードを表示
sqlite> .mode column
sqlite> select * from kanto_region;
code name
---- --------
101 tokyo
102 kanagawa
103 saitama
104 tiba
105 ibaragi
106 totigi
107 gunma
アタッチステートメントでmy_db.sq3データベースを作成する
---- region.sq3 データベースにアタッチしてみる
sqlite> attach database 'region.sq3' as region; -- 'region'というエイリアス名で登録する
sqlite> .databases
main: /home/takai/db/attach_sample/region.sq3 r/w -- sqlite3 コマンドで開いたdb
region: /home/takai/db/attach_sample/region.sq3 r/w -- r/wモードでregion名で接続されている
---- カレントデータベースの生成されているテーブルを確認してみる
sqlite> .tables
kanto_region region.kanto_region -- アタッチ用のテーブルが生成されている
---- テーブルの中身は同じである
sqlite> select * from kanto_region;
101|tokyo
102|kanagawa
103|saitama
104|tiba
105|ibaragi
106|totigi
107|gunma
sqlite> select * from region.kanto_region;
101|tokyo
102|kanagawa
103|saitama
104|tiba
105|ibaragi
106|totigi
107|gunma
---- my_db.sq3 データベースを作成する
sqlite> attach database 'my_db.sq3' as 'my_db';
sqlite> .databases
main: /home/takai/db/attach_sample/region.sq3 r/w
region: /home/takai/db/attach_sample/region.sq3 r/w
my_db: /home/takai/db/attach_sample/my_db.sq3 r/w -- 作成されたデータベースがアタッチされている
sqlite> .shell ls -la
合計 24
drwxr-xr-x 1 takai None 0 11月 27 18:28 .
drwxr-xr-x 1 takai None 0 11月 27 12:46 ..
-rwxr-xr-x 1 takai None 0 11月 27 18:28 my_db.sq3 -- データベースファイルが作成されている
-rwxr-xr-x 1 takai None 8192 11月 27 13:04 region.sq3
---- region.sq3 データベースを切断する
sqlite> detach database main;
Error: cannot detach database main -- main は予約用のため切断することが出来ない
sqlite> detach database region; -- region エイリアス名で切断する
sqlite> .databases
main: /home/takai/db/attach_sample/region.sq3 r/w -- kanto_regionテーブルがあるコマンドライン上のregion.sq3データベース
my_db: /home/takai/db/attach_sample/my_db.sq3 r/w
外部キー制約は使えない
---- 検証してみる
---- forengn key 使用設定を確認し 外部キーが使えるようにする
sqlite> pragma foreign_keys;
0
sqlite> pragma foreign_keys=On;
sqlite> pragma foreign_keys;
1
---- my_db データベースに外部キー制約をつけたmy_friend テーブルを作成する
-- foreign keyつきでmy_db.my_friend テーブルを作成してみる
sqlite> create table my_db.my_friend (
...> id integer primary key not null,
...> name text not null,
...> native_place integer,
...> foreign key(native_place) references kanto_region(code)
...> );
---- データを挿入してみる
sqlite> insert into my_db.my_friend values(
...> null, 'takai', 103
...> );
Error: no such table: my_db.kanto_region -- kanto_regionテーブルではアクセスできない
-- 異なるdatabase同士では 外部キー制約は使用できない!
-- トリガー処理も同様とおもわれる。
region.sql3 と my_db.sq3 のテーブル間で内部結合をする
.explain ?on|off|auto?
Change the EXPLAIN formatting mode. Default: auto
フォーマットモードの設定。デフォルトではheader=off colseparator: "|"
rowseparator: "\n"となる。on セットにすると .mode column と同じ画面表示設定になるようである。
---- 外部キー制約をつけないmy_friendテーブルに作り直す
sqlite> drop table my_db.my_friend;
sqlite> create table my_db.my_friend (
...> id integer primary key not null,
...> name text not null,
...> native_place integer
...> );
sqlite> .tables
kanto_region my_db.my_friend
---- 内部結合先 kanto_regionテーブルのレコードを確認する
sqlite> .explain on
sqlite> select * from kanto_region;
code name
---- -------------
101 tokyo
102 kanagawa
103 saitama
104 tiba
105 ibaragi
106 totigi
107 gunma
---- my_db.my_friendテーブルにレコードを挿入する
sqlite> insert into my_db.my_friend values(
...> null, 'takai', 103
...> );
sqlite> insert into my_friend values(
...> null, 'yamada', 102
...> );
sqlite> insert into my_friend values(
...> null, 'akiyama', 101
...> );
sqlite> insert into my_friend values(
...> null, 'kisida', 101
...> );
sqlite> insert into my_friend values(
...> null, 'suga', 105
...> );
sqlite> select * from my_db.my_friend;
id name nati
---- ------------- ----
1 takai 103
2 yamada 102
3 akiyama 101
4 kisida 101
5 suga 105
---- 内部結合してみる
sqlite> select * from my_db.my_friend inner join kanto_region on native_place=code;
id name nati code name
---- ------------- ---- ---- ----
1 takai 103 103 saitama
2 yamada 102 102 kanagawa
3 akiyama 101 101 tokyo
4 kisida 101 101 tokyo
5 suga 105 105 ibaragi
-- attach接続において、複数データベース間の内部結合は可能です。
出力先を変える操作
ドットコマンドの操作結果は、デフォルトでは、画面になっております。これを、ファイル出力に変えることにより、他のアプリケーションで利用したり、再度取り込んだりすることが可能になります。
.output ?FILE? Send output to FILE or stdout if FILE is omitted
sqlite3ドットコマンドの操作結果を、指定ファイルに書き込む。
ファイル名が存在しない場合は、新たに生成される。
If FILE begins with '|' then open it as a pipe.
Options:
--bom Prefix output with a UTF8 byte-order mark
-e Send output to the system text editor
-x Send output as CSV to a spreadsheet
.once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE
sqlite3ドットコマンドの操作結果を、指定ファイルに書き込む。
但し、書込み操作後は、出力先がデフォルト(画面)に戻る。
ファイル名が存在しない場合は、新たに生成される。
If FILE begins with '|' then open as a pipe
--bom Put a UTF8 byte-order mark at the beginning
-e Send output to the system text editor
-x Send output as CSV to a spreadsheet (same as ".excel")
---- ファイル出力する内容を確認
sqlite> select * from kanto_region;
code name
---- -------------
101 tokyo
102 kanagawa
103 saitama
104 tiba
105 ibaragi
106 totigi
107 gunma
---- 以降、出力先を kanto_region_output.txt にする
sqlite> .output kanto_region_output.txt
sqlite> select * from kanto_region;
---- 出力先を画面表示に戻す
sqlite> .output stdout
---- 出力先を kanto_region_once.txt にする
-- 一度だけ、出力したら、画面表示に戻っている
sqlite> .once kanto_region_once.txt
sqlite> select * from kanto_region;
---- 生成されたファイルを確認する
sqlite> .shell ls -la
合計 46
drwxr-xr-x 1 takai None 0 12月 17 13:05 .
drwxr-xr-x 1 takai None 0 12月 16 12:28 ..
-rw-r--r-- 1 takai None 180 12月 17 13:05 kanto_region_once.txt -- 生成されている
-rw-r--r-- 1 takai None 180 12月 17 13:05 kanto_region_output.txt -- 生成されている
-rwxr-xr-x 1 takai None 8192 12月 16 18:38 my_db.sq3
-rwxr-xr-x 1 takai None 8192 12月 16 12:41 region.sq3
sqlite> .shell cat kanto_region_output.txt
code name
---- -------------
101 tokyo
102 kanagawa
103 saitama
104 tiba
105 ibaragi
106 totigi
107 gunma
sqlite> .shell cat kanto_region_once.txt
code name
---- -------------
101 tokyo
102 kanagawa
103 saitama
104 tiba
105 ibaragi
106 totigi
107 gunma
CSVファイルとしてファイル出力する
region.sq3データベースのkanto_regionテーブルに格納されているレコードを出力してみます。
---- ヘッダー付きで出力する
sqlite> .headers on
sqlite> .mode csv
sqlite> .once kanto_region_with_header.csv
sqlite> select * from kanto_region;
sqlite> .shell ls -la
合計 47
drwxr-xr-x 1 takai None 0 12月 17 15:38 .
drwxr-xr-x 1 takai None 0 12月 16 12:28 ..
-rw-r--r-- 1 takai None 180 12月 17 13:05 kanto_region_once.txt
-rw-r--r-- 1 takai None 180 12月 17 13:05 kanto_region_output.txt
-rw-r--r-- 1 takai None 95 12月 17 15:38 kanto_region_with_header.csv -- 生成されている
-rwxr-xr-x 1 takai None 8192 12月 16 18:38 my_db.sq3
-rwxr-xr-x 1 takai None 8192 12月 16 12:41 region.sq3
---- ファイルの中身を確認する
sqlite> .shell cat kanto_region_with_header.csv
code,name
101,tokyo
102,kanagawa
103,saitama
104,tiba
105,ibaragi
106,totigi
107,gunma
---- ヘッダーなしで出力する
sqlite> .headers off
sqlite> .mode csv
sqlite> .once kanto_region.csv
sqlite> select * from kanto_region;
sqlite> .shell ls -la
合計 48
drwxr-xr-x 1 takai None 0 12月 17 22:34 .
drwxr-xr-x 1 takai None 0 12月 16 12:28 ..
-rw-r--r-- 1 takai None 84 12月 17 22:34 kanto_region.csv -- 生成されている
-rw-r--r-- 1 takai None 180 12月 17 13:05 kanto_region_once.txt
-rw-r--r-- 1 takai None 180 12月 17 13:05 kanto_region_output.txt
-rw-r--r-- 1 takai None 95 12月 17 15:38 kanto_region_with_header.csv
-rwxr-xr-x 1 takai None 8192 12月 16 18:38 my_db.sq3
-rwxr-xr-x 1 takai None 8192 12月 16 12:41 region.sq3
---- ファイルの中身を確認する
sqlite> .shell cat kanto_region.csv
101,tokyo
102,kanagawa
103,saitama
104,tiba
105,ibaragi
106,totigi
107,gunma
CSVファイルをデータベーステーブルのレコードとして取り込む
.import FILE TABLE Import data from FILE into TABLE
CSV または同様に区切られたデータを SQLite テーブルにインポートします。
Options:
--ascii Use \037 and \036 as column and row separators
--csv Use , and \n as column and row separators
--skip N Skip the first N rows of input
-v "Verbose" - increase auxiliary output
Notes:
* If TABLE does not exist, it is created. The first row of input
determines the column names.
* If neither --csv or --ascii are used, the input mode is derived
from the ".mode" output mode
* If FILE begins with "|" then it is a command that generates the
input text
---- my_dbデータベースのmy_friendテーブルのレコードをcsvファイルとして出力する
sqlite> .headers on
sqlite> .mode csv
sqlite> .once my_friend_with_header.csv
sqlite> select * from my_db.my_friend;
---- 作成されているかを確認
sqlite> .shell ls -la
合計 37
drwxr-xr-x 1 takai None 0 12月 18 23:09 .
drwxr-xr-x 1 takai None 0 12月 16 12:28 ..
-rw-r--r-- 1 takai None 84 12月 17 22:34 kanto_region.csv
-rw-r--r-- 1 takai None 180 12月 17 13:05 kanto_region_once.txt
-rw-r--r-- 1 takai None 180 12月 17 13:05 kanto_region_output.txt
-rw-r--r-- 1 takai None 95 12月 17 15:38 kanto_region_with_header.csv
-rwxr-xr-x 1 takai None 8192 12月 18 23:09 my_db.sq3
-rwxr-xr-x 1 takai None 90 12月 18 18:50 my_friend_with_header.csv -- 生成されている
-rwxr-xr-x 1 takai None 8192 12月 18 22:48 region.sq3
---- 表計算ソフトまたはテキストエディタをたちあげ、生成されたmy_friend_with_header.csvを開く
-- レコードを追加する
-- 上書き保存をする。
-- 尚、ここでは、以下、データは、以下のcsvが追加されたとして進めます。
sqlite> .shell cat my_friend_with_header.csv
id,name,native_place
1,takai,103
2,yamada,102
3,akiyama,101
4,kisida,101
5,suga,105
6,nisida,104 -- 表計算ソフトによる追加データ
7,kimura,101 -- 表計算ソフトによる追加データ
---- データを追加したcsvファイルをインポートする。
-- attach接続ではインポート処理はうまくいかない。
sqlite> .quit
---- my_db.sq3データベースを開く
takai@takai-pc ~/db/attach_sample2
$ sqlite3 my_db.sq3
SQLite version 3.34.0 2020-12-01 16:14:00
Enter ".help" for usage hints.
---- 格納されているmy_friendテーブルの中身を確認する
sqlite> .tables
my_friend
sqlite> select * from my_friend;
1|takai|103
2|yamada|102
3|akiyama|101
4|kisida|101
5|suga|105
---- csvファイルをmy_friendテーブルにインポートする
-- 追加したデータのみmy_friendテーブルレコードに追記するのでcsvファイル最初の6行スキップする。
sqlite> .import --csv --skip 6 ./my_friend_with_header.csv my_friend
---- インポート後のテーブルレコードを確認する
sqlite> select * from my_friend;
1|takai|103
2|yamada|102
3|akiyama|101
4|kisida|101
5|suga|105
6|nisida|104 -- 追記されている
7|kimura|101 -- 追記されている
sqlite> .shell ls -la
合計 37
drwxr-xr-x 1 takai None 0 12月 18 23:09 .
drwxr-xr-x 1 takai None 0 12月 16 12:28 ..
-rw-r--r-- 1 takai None 84 12月 17 22:34 kanto_region.csv
-rw-r--r-- 1 takai None 180 12月 17 13:05 kanto_region_once.txt
-rw-r--r-- 1 takai None 180 12月 17 13:05 kanto_region_output.txt
-rw-r--r-- 1 takai None 95 12月 17 15:38 kanto_region_with_header.csv
-rwxr-xr-x 1 takai None 8192 12月 18 23:09 my_db.sq3
-rwxr-xr-x 1 takai None 118 12月 18 18:50 my_friend_with_header.csv
-rwxr-xr-x 1 takai None 8192 12月 18 22:48 region.sq3
フォーマット形式ファイルとして出力できるもの
下記のようなモード設定をすれば、そのモード形式のファイルとして出力できます。
.mode MODE ?TABLE? Set output mode
MODE is one of:
ascii Columns/rows delimited by 0x1F and 0x1E
box Tables using unicode box-drawing characters
csv Comma-separated values
column Output in columns. (See .width)
html HTML <table> code
insert SQL insert statements for TABLE
json Results in a JSON array
line One value per line
list Values delimited by "|"
markdown Markdown table format
quote Escape answers as for SQL
table ASCII-art table
tabs Tab-separated values
tcl TCL list elements
.show Show the current values for various settings
表示に係わる項目の設定値を表示する
---- 画面設定値を確認
sqlite> .show
echo: off
eqp: off
explain: auto
headers: off -- onに
mode: list -- htmlに
nullvalue: ""
output: stdout
colseparator: "|"
rowseparator: "\n"
stats: off
width:
filename: my_db.sq3
---- htmlとして出力する
sqlite> .headers on
sqlite> .mode html
sqlite> .once ./my_friend.html
sqlite> select * from my_friend;
---- 出力されたhtmlファイルを確認する
sqlite> .shell cat my_friend.html
<TR><TH>id</TH>
<TH>name</TH>
<TH>native_place</TH>
</TR>
<TR><TD>1</TD>
<TD>takai</TD>
<TD>103</TD>
</TR>
<TR><TD>2</TD>
<TD>yamada</TD>
<TD>102</TD>
</TR>
<TR><TD>3</TD>
<TD>akiyama</TD>
<TD>101</TD>
</TR>
<TR><TD>4</TD>
<TD>kisida</TD>
<TD>101</TD>
</TR>
<TR><TD>5</TD>
<TD>suga</TD>
<TD>105</TD>
</TR>
<TR><TD>6</TD>
<TD>nisida</TD>
<TD>104</TD>
</TR>
<TR><TD>7</TD>
<TD>kimura</TD>
<TD>101</TD>
</TR>
---- jsonファイルとして出力する
sqlite> .mode json
sqlite> .once my_friend.json
sqlite> select * from my_friend;
sqlite> .shell cat my_friend.json
[{"id":1,"name":"takai","native_place":103},
{"id":2,"name":"yamada","native_place":102},
{"id":3,"name":"akiyama","native_place":101},
{"id":4,"name":"kisida","native_place":101},
{"id":5,"name":"suga","native_place":105},
{"id":6,"name":"nisida","native_place":104},
{"id":7,"name":"kimura","native_place":101}]
sqlite> .shell ls -la
合計 39
drwxr-xr-x 1 takai None 0 12月 19 15:29 .
drwxr-xr-x 1 takai None 0 12月 16 12:28 ..
-rw-r--r-- 1 takai None 84 12月 17 22:34 kanto_region.csv
-rw-r--r-- 1 takai None 180 12月 17 13:05 kanto_region_once.txt
-rw-r--r-- 1 takai None 180 12月 17 13:05 kanto_region_output.txt
-rw-r--r-- 1 takai None 95 12月 17 15:38 kanto_region_with_header.csv
-rwxr-xr-x 1 takai None 8192 12月 18 23:09 my_db.sq3
-rw-r--r-- 1 takai None 406 12月 19 15:22 my_friend.html -- 生成
-rw-r--r-- 1 takai None 314 12月 19 15:30 my_friend.json -- 生成
-rwxr-xr-x 1 takai None 118 12月 18 18:50 my_friend_with_header.csv
-rwxr-xr-x 1 takai None 8192 12月 18 22:48 region.sq3
データベースファイルの再構築
複数のデータベースをアタッチ接続しても、外部キー制約が使えません。外部キーの親キーが変更されても、異なるデータベースが、その外部キーをもっ ていても変更が反映されないことになります。親キーとなる、異なるデータベースをその外部キーを持つデータベースにまとめてしまえば、外部キー制約を使う ことが出来ます。但し、親キーの変更は、どこかの時点で、そのことを感知し、その都度、親キーをもつテーブルを取り込む必要があります。このようなことが あるので、親キーを持つテーブルは頻繁に更新しないデータであるのが望ましいと思われます。
.dump ?TABLE? Render database content as SQL
データベースの指定テーブルの内容を SQL 文の形式で出力
Options:
--data-only Output only INSERT statements
--newlines Allow unescaped newline characters in output
--nosys Omit system tables (ex: "sqlite_stat1")
--preserve-rowids Include ROWID values in the output
TABLE is a LIKE pattern for the tables to dump
Additional LIKE patterns can be given in subsequent arguments
.read FILE Read input from FILE
ダンプした内容を読み込む
ここでは、外部キー制約を使えるように、アタッチ接続されたデータベースの親キーを持つテーブルregion.kanto_regionをメインとなるデータベースmy_dbに取り込みます。下記のような手順で行っております。
- regionデータベースを開きます。
- region.sq3データベースからkanto_regionテーブル情報をkanto_region_dump.txtとしてダンプします。
- regionデータベースを閉じます。
- 再構築先のデータベースmy_dbを開きます。
- my_friendテーブルのデータをファイルmy_friend_with_header.csv出力します。–> 前項で出力済み
- kanto_regionテーブルを親キーとする、外部キー制約列のあるnew_my_friendテーブルを生成します。
- my_friendテーブルのデータmy_friend_with_header.csvをmy_dbデータベースのnew_my_friendテーブルにインポートします。
- ダンプ出力されたkanto_regionテーブル情報ファイルkanto_region_dump.txtをmy_dbデータベースに取り込みます。
- 外部キーを有効にします。
- my_friendテーブルを削除します。
sqlite> .quit
---- region.sq3データベースからkanto_regionテーブル情報をダンプする
takai@takai-pc ~/db/attach_sample
$ sqlite3 region.sq3
SQLite version 3.34.0 2020-12-01 16:14:00
Enter ".help" for usage hints.
sqlite> .tables
kanto_region
---- ダンプする kanto_region テーブルの中身を確認する
sqlite> .dump kanto_region
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE kanto_region (
code integer primary key not null,
name text not null
);
INSERT INTO kanto_region VALUES(101,'tokyo');
INSERT INTO kanto_region VALUES(102,'kanagawa');
INSERT INTO kanto_region VALUES(103,'saitama');
INSERT INTO kanto_region VALUES(104,'tiba');
INSERT INTO kanto_region VALUES(105,'ibaragi');
INSERT INTO kanto_region VALUES(106,'totigi');
INSERT INTO kanto_region VALUES(107,'gunma');
COMMIT;
---- ダンプ内容をファイルに出力する
sqlite> .once ./kanto_region_dump.txt
sqlite> .dump kanto_region
sqlite> .shell ls -la
合計 44
drwxr-xr-x 1 takai None 0 12月 20 12:55 .
drwxr-xr-x 1 takai None 0 12月 16 12:28 ..
-rw-r--r-- 1 takai None 84 12月 17 22:34 kanto_region.csv
-rw-r--r-- 1 takai None 470 12月 20 12:55 kanto_region_dump.txt -- dump出力されたファイル
-rw-r--r-- 1 takai None 180 12月 17 13:05 kanto_region_once.txt
-rw-r--r-- 1 takai None 180 12月 17 13:05 kanto_region_output.txt
-rw-r--r-- 1 takai None 95 12月 17 15:38 kanto_region_with_header.csv
-rwxr-xr-x 1 takai None 8192 12月 20 12:30 my_db.sq3
-rw-r--r-- 1 takai None 406 12月 19 15:22 my_friend.html
-rw-r--r-- 1 takai None 314 12月 19 15:30 my_friend.json
-rwxr-xr-x 1 takai None 118 12月 18 18:50 my_friend_with_header.csv
-rwxr-xr-x 1 takai None 8192 12月 18 22:48 region.sq3
---- 再構築先のデータベースを開く
sqlite> .quit
takai@takai-pc ~/db/attach_sample
$ sqlite3 my_db.sq3
SQLite version 3.34.0 2020-12-01 16:14:00
Enter ".help" for usage hints.
sqlite> .tables
my_friend
---- 外部キー制約のあるnew_my_friend テーブルを作成する
sqlite> create table new_my_friend (
...> id integer primary key not null,
...> name text not null,
...> native_place integer references kanto_region (code)
...> );
---- レコードをインポートするファイル内容を確認
sqlite> .shell cat my_friend_with_header.csv
id,name,native_place
1,takai,103
2,yamada,102
3,akiyama,101
4,kisida,101
5,suga,105
6,nisida,104
7,kimura,101
---- レコードをインポートする
sqlite> .import --csv --skip 1 ./my_friend_with_header.csv new_my_friend
---- インポートされたレコードを確認する
sqlite> select * from new_my_friend;
1|takai|103
2|yamada|102
3|akiyama|101
4|kisida|101
5|suga|105
6|nisida|104
7|kimura|101
---- ダンプ出力されたファイルを取り込む
sqlite> .read ./kanto_region_dump.txt
sqlite> .tables
kanto_region my_friend new_my_friend
---- new_my_friendテーブルにkanto_regionテーブルを内部結合してみる
sqlite> .mode column
sqlite> select * from new_my_friend inner join kanto_region on native_place=code;
id name nati code name
---- ------------- ---- ---- ----
1 takai 103 103 saitama
2 yamada 102 102 kanagawa
3 akiyama 101 101 tokyo
4 kisida 101 101 tokyo
5 suga 105 105 ibaragi
6 nisida 104 104 tiba
7 kimura 101 101 tokyo
sqlite> .quit
$ sqlite3 my_db.sq3
SQLite version 3.34.0 2020-12-01 16:14:00
Enter ".help" for usage hints.
---- 外部キーを有効にする
sqlite> pragma foreign_keys;
0
sqlite> pragma foreign_keys=on;
sqlite> pragma foreign_keys;
1
sqlite> .tables
kanto_region my_friend new_my_friend
---- 外部キー制約の確認
sqlite> delete from kanto_region where code=101;
Error: FOREIGN KEY constraint failed
sqlite> update kanto_region set code=100 where code=101;
Error: FOREIGN KEY constraint failed
---- 以前のテーブルを削除
sqlite> drop table my_friend;
sqlite> .tables
kanto_region new_my_friend
データベース ファイル構造のクリーンアップ VACUUMコマンド
VACUUM コマンドは、メイン データベースの内容を一時データベース ファイルにコピーし、そのコピーから元のデータベース ファイルを再ロードすることによって、メイン データベースをクリーンアップします。これにより、空き ページが削除され、テーブル データが連続するように配置され、データベース ファイル構造がコンパクトになります。
- データベース ファイルから大量のデータが削除されると、空のスペース、つまりファイルサイズは変らず、「空き」があるデータベース ページになります。VACUUM を実行してデータベースを再構築すると、この領域が再利用され、データベース ファイルのサイズが削減されます。
- 再構築には、一時データベースファイルにコピーできる分の空き容量が必要とされます。
- VACUUM コマンド実行には、トランザクションの場合と同様に、ロールバック ジャーナルまたは先行書き込みログWAL ファイルが使用されます。
- VACUUM を実行しようとしているデータベース接続上に開いているトランザクションがある場合、VACUUM は失敗します。
- VACUUM コマンドは、明示的な INTEGER PRIMARY KEY を持たないテーブル内のエントリの ROWID を変更する場合があります。
VACUUMコマンドでクリーンアップしてみる
コマンドプロンプトから
$sqlite3 database_name "VACUUM;"
SQLiteプロンプトから
sqlite> VACUUM;
sqlite> VACUUM table_name;
VACUUM database_name/table_name INTO filename
元のデータベース ファイルは変更されず、INTO 句の引数で指定されたファイルに新しいデータベースが作成されます。
ライブ データベースのバックアップ コピーを生成するためのバックアップ APIの代替手段となります。
ファイルは、空のファイルである必要があります。
sqlite> .quit
takai@takai-pc ~/db/attach_sample
$ ls -la
合計 36
drwxr-xr-x 1 takai None 0 4月 14 15:55 .
drwxr-xr-x 1 takai None 0 4月 11 12:32 ..
-rw-r--r-- 1 takai None 84 4月 11 17:58 kanto_region.csv
-rw-r--r-- 1 takai None 470 4月 11 22:40 kanto_region_dump.txt
-rw-r--r-- 1 takai None 180 4月 11 17:50 kanto_region_once.txt
-rw-r--r-- 1 takai None 180 4月 11 15:25 kanto_region_output.txt
-rw-r--r-- 1 takai None 95 4月 11 17:56 kanto_region_with_header.csv
-rwxr-xr-x 1 takai None 16384 4月 12 18:39 my_db.sq3 -- 再構築されたデータベースファイル
-rw-r--r-- 1 takai None 406 4月 11 18:22 my_friend.html
-rw-r--r-- 1 takai None 314 4月 11 18:23 my_friend.json
-rw-r--r-- 1 takai None 118 4月 11 18:12 my_friend_with_header.csv
-rwxr-xr-x 1 takai None 8192 4月 13 22:34 region.sq3
---- my_db.sq3データベースファイルをクリーンアップし、my_db_vacummed.sq3データベースファイルをつくる。
takai@takai-pc ~/db/attach_sample
$ sqlite3 my_db.sq3
SQLite version 3.34.0 2020-12-01 16:14:00
Enter ".help" for usage hints.
sqlite> .tables
kanto_region new_my_friend
---- vacuum into コマンドを実行
sqlite> vacuum main into 'my_db_vacuumed.sq3';
sqlite> .shell ls -la
合計 48
drwxr-xr-x 1 takai None 0 4月 14 15:59 .
drwxr-xr-x 1 takai None 0 4月 11 12:32 ..
-rw-r--r-- 1 takai None 84 4月 11 17:58 kanto_region.csv
-rw-r--r-- 1 takai None 470 4月 11 22:40 kanto_region_dump.txt
-rw-r--r-- 1 takai None 180 4月 11 17:50 kanto_region_once.txt
-rw-r--r-- 1 takai None 180 4月 11 15:25 kanto_region_output.txt
-rw-r--r-- 1 takai None 95 4月 11 17:56 kanto_region_with_header.csv
-rwxr-xr-x 1 takai None 16384 4月 12 18:39 my_db.sq3
-rwxr-xr-x 1 takai None 12288 4月 14 15:59 my_db_vacuumed.sq3 -- 生成されたファイル
-rw-r--r-- 1 takai None 406 4月 11 18:22 my_friend.html
-rw-r--r-- 1 takai None 314 4月 11 18:23 my_friend.json
-rw-r--r-- 1 takai None 118 4月 11 18:12 my_friend_with_header.csv
-rwxr-xr-x 1 takai None 8192 4月 13 22:34 region.sq3
-- 16384 -> 12288 にサイズが縮小している。
---- 生成されたmy_db_vacuumed.sq3データベースファイルの中身を確認
sqlite> .open my_db_vacuumed.sq3
sqlite> .tables
kanto_region new_my_friend
sqlite> .databases
main: /home/takai/db_chk/attach_sample/my_db_vacuumed.sq3 r/w
sqlite> select * from kanto_region;
101|tokyo
102|kanagawa
103|saitama
104|tiba
105|ibaraki
106|totigi
107|gunma
sqlite> select * from new_my_friend;
1|takai|103
2|yamada|102
3|akiyama|101
4|kisida|101
5|suga|105
6|nisida|104
7|kimura|101
自動バキューム
自動バキュームは、空きページをデータベースの最後に移動し、データベースのサイズを縮小させるのをプラグマ設定で行います。
sqlite> pragma auto_vacuum; -- デフォルト 0
自動バキューム設定の確認
sqlite> PRAGMA auto_vacuum = NONE; -- 0
自動バキューム モードを無効にします
sqlite> PRAGMA auto_vacuum = FULL; -- 1
自動バキューム モードを有効にします
sqlite> PRAGMA auto_vacuum = INCREMENTAL; -- 2
増分バキュームを有効にします。
バックアップ
.backup ?DB? FILE Backup DB (default "main") to FILE
--append Use the appendvfs
--async Write to FILE without journal and fsync()
データベース ファイルに共有ロックを確立します。
.restore ?DB? FILE Restore content of DB (default "main") from FILE
現在接続しているデータベースに含まれているテーブルやデータなどがすべて削除された上でリストアが行われます
---- カレントデータベースをバックアップする
sqlite> .databases
main: /home/takai/db/attach_sample/my_db_vacuumed.sq3 r/w
sqlite> .backup ./my_db_vacuumed.bk
sqlite> .quit
takai@takai-pc ~/db/attach_sample
$ ls -la
合計 60
drwxr-xr-x 1 takai None 0 4月 14 18:12 .
drwxr-xr-x 1 takai None 0 4月 11 12:32 ..
-rw-r--r-- 1 takai None 84 4月 11 17:58 kanto_region.csv
-rw-r--r-- 1 takai None 470 4月 11 22:40 kanto_region_dump.txt
-rw-r--r-- 1 takai None 180 4月 11 17:50 kanto_region_once.txt
-rw-r--r-- 1 takai None 180 4月 11 15:25 kanto_region_output.txt
-rw-r--r-- 1 takai None 95 4月 11 17:56 kanto_region_with_header.csv
-rwxr-xr-x 1 takai None 16384 4月 12 18:39 my_db.sq3
-rwxr-xr-x 1 takai None 12288 4月 14 18:12 my_db_vacuumed.bk -- バックアップファイル
-rwxr-xr-x 1 takai None 12288 4月 14 15:59 my_db_vacuumed.sq3
-rw-r--r-- 1 takai None 406 4月 11 18:22 my_friend.html
-rw-r--r-- 1 takai None 314 4月 11 18:23 my_friend.json
-rw-r--r-- 1 takai None 118 4月 11 18:12 my_friend_with_header.csv
-rwxr-xr-x 1 takai None 8192 4月 13 22:34 region.sq3
---- restored ディレクトリにバックアップファイルとリストアーされたファイルを作る
takai@takai-pc ~/db_chk/attach_sample
$ mkdir restored
takai@takai-pc ~/db/attach_sample
$ sqlite3 my_db_vacuumed.sq3
SQLite version 3.34.0 2020-12-01 16:14:00
Enter ".help" for usage hints.
---- バックアップファイル生成
sqlite> .backup restored/my_db.bk
sqlite> .quit
-- バックアップファイルを確認する
takai@takai-pc ~/db_chk/attach_sample
$ cd restored/
takai@takai-pc ~/db_chk/attach_sample/restored
$ ls -la
合計 16
drwxr-xr-x 1 takai None 0 4月 14 18:18 .
drwxr-xr-x 1 takai None 0 4月 14 18:17 ..
-rwxr-xr-x 1 takai None 12288 4月 14 18:18 my_db.bk -- バックアップファイルが生成されている
takai@takai-pc ~/db_chk/attach_sample/restored
$ sqlite3 restored_my_db.sq3
SQLite version 3.34.0 2020-12-01 16:14:00
Enter ".help" for usage hints.
---- リストアーファイルを生成
sqlite> .restore ./my_db.bk
sqlite> .databases
main: /home/takai/db_chk/attach_sample/restored/restored_my_db.sq3 r/w
sqlite> .tables
kanto_region new_my_friend
sqlite> .shell ls -a
. .. my_db.bk restored_my_db.sq3
sqlite> .shell ls -la
合計 32
drwxr-xr-x 1 takai None 0 4月 14 18:22 .
drwxr-xr-x 1 takai None 0 4月 14 18:17 ..
-rwxr-xr-x 1 takai None 12288 4月 14 18:18 my_db.bk
-rwxr-xr-x 1 takai None 12288 4月 14 18:22 restored_my_db.sq3 -- リストアーファイル生成
---- my_db.sq3データベースにレコードを追加し、バックアップする
sqlite> .quit
takai@takai-pc ~/db/attach_sample/restored
$ cd ..
takai@takai-pc ~/db/attach_sample
$ sqlite3 my_db.sq3
SQLite version 3.34.0 2020-12-01 16:14:00
Enter ".help" for usage hints.
sqlite> .tables
kanto_region new_my_friend
sqlite> select * from new_my_friend;
1|takai|103
2|yamada|102
3|akiyama|101
4|kisida|101
5|suga|105
6|nisida|104
7|kimura|101
---- new_my_freindにレコードを追加する
sqlite> insert into new_my_friend values(
...> null, 'kameda', 107
...> );
---- カレントディレクトリにバックアップファイルを生成する
sqlite> .backup ./my_db.bk
sqlite> .shell ls -la
合計 76
drwxr-xr-x 1 takai None 0 4月 17 12:45 .
drwxr-xr-x 1 takai None 0 4月 11 12:32 ..
-rw-r--r-- 1 takai None 84 4月 11 17:58 kanto_region.csv
-rw-r--r-- 1 takai None 470 4月 11 22:40 kanto_region_dump.txt
-rw-r--r-- 1 takai None 180 4月 11 17:50 kanto_region_once.txt
-rw-r--r-- 1 takai None 180 4月 11 15:25 kanto_region_output.txt
-rw-r--r-- 1 takai None 95 4月 11 17:56 kanto_region_with_header.csv
-rwxr-xr-x 1 takai None 16384 4月 17 12:45 my_db.bk -- 生成されたバックアップファイル
-rwxr-xr-x 1 takai None 16384 4月 17 12:44 my_db.sq3
-rwxr-xr-x 1 takai None 12288 4月 14 18:12 my_db_vacuumed.bk
-rwxr-xr-x 1 takai None 12288 4月 14 15:59 my_db_vacuumed.sq3
-rw-r--r-- 1 takai None 406 4月 11 18:22 my_friend.html
-rw-r--r-- 1 takai None 314 4月 11 18:23 my_friend.json
-rw-r--r-- 1 takai None 118 4月 11 18:12 my_friend_with_header.csv
-rwxr-xr-x 1 takai None 8192 4月 13 22:34 region.sq3
drwxr-xr-x 1 takai None 0 4月 14 18:22 restore
sqlite> select * from new_my_friend;
1|takai|103
2|yamada|102
3|akiyama|101
4|kisida|101
5|suga|105
6|nisida|104
7|kimura|101
8|kameda|107
---- restoredディレクトリにバックアップ
sqlite> .backup restored/my_db2.bk
sqlite> .quit
takai@takai-pc ~/db/attach_sample
$ cd restored
takai@takai-pc ~/db/attach_sample/restored
$ ls -la
合計 44
drwxr-xr-x 1 takai None 0 4月 17 18:27 .
drwxr-xr-x 1 takai None 0 4月 17 12:56 ..
-rwxr-xr-x 1 takai None 12288 4月 14 18:18 my_db.bk
-rwxr-xr-x 1 takai None 16384 4月 17 18:27 my_db2.bk
-rwxr-xr-x 1 takai None 12288 4月 14 18:22 restored_my_db.sq3
---- 追記したmy_db2.bkをrestored_my_db.sq3データベースファイルに上書きする
takai@takai-pc ~/db/attach_sample/restored
$ sqlite3 restored_my_db2.sq3
SQLite version 3.34.0 2020-12-01 16:14:00
Enter ".help" for usage hints.
sqlite> .restore ./my_db2.bk
sqlite> select * from new_my_friend;
1|takai|103
2|yamada|102
3|akiyama|101
4|kisida|101
5|suga|105
6|nisida|104
7|kimura|101
8|kameda|107
sqlite> .shell ls -la
合計 52
drwxr-xr-x 1 takai None 0 4月 17 18:33 .
drwxr-xr-x 1 takai None 0 4月 17 12:56 ..
-rwxr-xr-x 1 takai None 12288 4月 14 18:18 my_db.bk
-rwxr-xr-x 1 takai None 16384 4月 17 18:27 my_db2.bk -- 追記したバックアップファイル
-rwxr-xr-x 1 takai None 16384 4月 17 18:33 restored_my_db.sq3 -- 上書きしたリストアファイル
アーカイブ
.archive ... Manage SQL archives
アーカイブファイルの作成、展開
Each command must have exactly one of the following options:
-c, --create Create a new archive
-u, --update Add or update files with changed mtime
-i, --insert Like -u but always add even if unchanged
-t, --list List contents of archive
-x, --extract Extract files from archive
Optional arguments:
-v, --verbose Print each filename as it is processed
-f FILE, --file FILE Use archive FILE (default is current db)
-a FILE, --append FILE Open FILE using the apndvfs VFS
-C DIR, --directory DIR Read/extract files from directory DIR
-n, --dryrun Show the SQL that would have occurred
Examples:
.ar -cf ARCHIVE foo bar # Create ARCHIVE from files foo and bar
.ar -tf ARCHIVE # List members of ARCHIVE
.ar -xvf ARCHIVE # Verbosely extract files from ARCHIVE
See also:
http://sqlite.org/cli.html#sqlar_archive_support
sqlite> .quit
takai@takai-pc ~/db/attach_sample/restored
$ cd ..
---- archiveディレクトリを作成する
takai@takai-pc ~/db/attach_sample
$ mkdir archive
---- アーカイブ対象データベースを開く
takai@takai-pc ~/db/attach_sample
$ sqlite3 my_db.sq3
SQLite version 3.34.0 2020-12-01 16:14:00
Enter ".help" for usage hints.
sqlite> attach database 'region.sq3' as 'region';
sqlite> attach database 'my_db.sq3' as 'my_db';
sqlite> .databases
main: /home/takai/db/attach_sample2/my_db.sq3 r/w
region: /home/takai/db/attach_sample2/region.sq3 r/w
my_db: /home/takai/db/attach_sample2/my_db.sq3 r/w
---- カレントディレクトリ、archive ディレクトリにアーカイブファイルを作成する
sqlite> .ar -cf ARCHIVE1 my_db.sq3 region.sq3
sqlite> .ar -cf archive/ARCHIVE1 my_db.sq3 region.sq3
sqlite> .quit
takai@takai-pc ~/db/attach_sample2
$ cd archive
---- ファイル生成確認
takai@takai-pc ~/db/attach_sample2/archive
$ ls -la
合計 8
drwxr-xr-x 1 takai None 0 4月 17 22:28 .
drwxr-xr-x 1 takai None 0 4月 17 22:27 ..
-rwxr-xr-x 1 takai None 2048 4月 17 22:28 ARCHIVE1 -- アーカイブファイルが生成されている
takai@takai-pc ~/db/attach_sample2/archive
$ sqlite3
SQLite version 3.34.0 2020-12-01 16:14:00
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
---- アーカイブファイルの中身を確認する
sqlite> .ar -tf ARCHIVE1
my_db.sq3
region.sq3
---- アーカイブファイルを解凍する
sqlite> .ar -xvf ARCHIVE1
my_db.sq3
region.sq3
sqlite> .shell ls -la
合計 32
drwxr-xr-x 1 takai None 0 4月 17 22:32 .
drwxr-xr-x 1 takai None 0 4月 17 22:27 ..
-rwxr-xr-x 1 takai None 2048 4月 17 22:28 ARCHIVE1
-rwxr-xr-x 1 takai None 16384 4月 17 12:44 my_db.sq3 -- 解凍されたデータベースファイル
-rwxr-xr-x 1 takai None 8192 4月 13 22:34 region.sq3 -- 解凍されたデータベースファイル