データベースの一部のSQLite3テーブル(すべてのテーブルではなく)のデータで、スキーマではなくデータのみをダンプするにはどうすればよいですか?ダンプは、後でデータベースに簡単に再入力し、コマンドラインから実行する必要があるため、SQL形式にする必要があります。何かのようなもの
sqlite3 db .dump
ただし、スキーマをダンプし、ダンプするテーブルを選択することはありません。
ダンプされたファイルで何をしたいのかを言わない。
次を使用してCSVファイルを取得します。これをほぼすべてにインポートできます
.mode csv
-- use '.separator SOME_STRING' for something other than a comma.
.headers on
.out file.csv
select * from MyTable;
別のSQLiteデータベースに再挿入する場合:
.mode insert <target_table_name>
.out file.sql
select * from MyTable;
これを行うと、.schemaコマンドと.dumpコマンドの違いを取得できます。たとえば、grepを使用した場合:
sqlite3 some.db .schema > schema.sql
sqlite3 some.db .dump > dump.sql
grep -vx -f schema.sql dump.sql > data.sql
data.sql
ファイルには、次のようなスキーマのないデータのみが含まれます。
BEGIN TRANSACTION;
INSERT INTO "table1" VALUES ...;
...
INSERT INTO "table2" VALUES ...;
...
COMMIT;
これがあなたのお役に立てば幸いです。
最良の方法ではありませんが、少なくとも* nixボックスの標準であるgrepを除き、少なくとも外部ツールは必要ありません
sqlite3 database.db3 .dump | grep '^INSERT INTO "tablename"'
ただし、探しているテーブルごとにこのコマンドを実行する必要があります。
これにはスキーマが含まれないことに注意してください。
.dump特殊コマンドに1つ以上のテーブル引数を指定できます(例:sqlite3 db ".dump 'table1' 'table2'"
)。
Grepを使用してCREATE
行を除外すること、またはsqlite3 $DB .dump
出力からINSERT
行を取得することを示唆する回答は、すべて失敗します。 CREATE TABLE
コマンドは行ごとに1列をリストし(したがって、CREATE
を除くとすべてを取得できません)、INSERT
行の値に改行を埋め込むことができます(したがって、INSERT
行だけを取得することはできません)。
for t in $(sqlite3 $DB .tables); do
echo -e ".mode insert $t\nselect * from $t;"
done | sqlite3 $DB > backup.sql
Sqlite3バージョン3.6.20でテスト済み。
特定のテーブルを除外する場合は、$(sqlite $DB .tables | grep -v -e one -e two -e three)
でフィルター処理するか、特定のサブセットを取得する場合は、one two three
で置き換えます。
ポール・イーガンの答えの改善として、これは次のように達成できます。
sqlite3 database.db3 '.dump "table1" "table2"' | grep '^INSERT'
-または-
sqlite3 database.db3 '.dump "table1" "table2"' | grep -v '^CREATE'
もちろん、警告はgrepをインストールする必要があるということです。
PythonまたはJavaまたは高水準言語では、.dumpは機能しません。変換を手動でCSVにコーディングする必要があります。 Pythonの例を挙げます。その他、例に感謝します:
from os import path
import csv
def convert_to_csv(directory, db_name):
conn = sqlite3.connect(path.join(directory, db_name + '.db'))
cursor = conn.cursor()
cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
tables = cursor.fetchall()
for table in tables:
table = table[0]
cursor.execute('SELECT * FROM ' + table)
column_names = [column_name[0] for column_name in cursor.description]
with open(path.join(directory, table + '.csv'), 'w') as csv_file:
csv_writer = csv.writer(csv_file)
csv_writer.writerow(column_names)
while True:
try:
csv_writer.writerow(cursor.fetchone())
except csv.Error:
break
「パネルデータ」、つまりIDを持つ多くの個別エントリがある場合、これをwithルックに追加し、要約統計もダンプします。
if 'id' in column_names:
with open(path.join(directory, table + '_aggregate.csv'), 'w') as csv_file:
csv_writer = csv.writer(csv_file)
column_names.remove('id')
column_names.remove('round')
sum_string = ','.join('sum(%s)' % item for item in column_names)
cursor.execute('SELECT round, ' + sum_string +' FROM ' + table + ' GROUP BY round;')
csv_writer.writerow(['round'] + column_names)
while True:
try:
csv_writer.writerow(cursor.fetchone())
except csv.Error:
break
SQLiteのコマンドラインシェル のSQLiteドキュメントによると、単に "mode"を "csv"に設定してから、SQLiteテーブル(またはテーブルの一部)をCSVとしてエクスポートできます。テーブルの目的の行を抽出するクエリ:
sqlite> .header on
sqlite> .mode csv
sqlite> .once c:/work/dataout.csv
sqlite> SELECT * FROM tab1;
sqlite> .exit
次に、「。import」コマンドを使用して、CSV(カンマ区切り値)データをSQLiteテーブルにインポートします。
sqlite> .mode csv
sqlite> .import C:/work/dataout.csv tab1
sqlite> .exit
考慮すべき2つのケースに関する詳細なドキュメントをお読みください:(1)テーブル "tab1"が以前に存在しない、および(2)テーブル "tab1"が既に存在する。
最良の方法は、スキーマパーツを除き、sqlite3 dbダンプが実行するコードを取得することです。
擬似コードの例:
SELECT 'INSERT INTO ' || tableName || ' VALUES( ' ||
{for each value} ' quote(' || value || ')' (+ commas until final)
|| ')' FROM 'tableName' ORDER BY rowid DESC
実際のコードについては、src/Shell.c:838
(sqlite-3.5.9用)を参照してください
そのシェルを取り出して、スキーマパーツをコメントアウトして使用することもできます。
INSERTのみを含める
sqlite3 database.db3 .dump | grep '^INSERT INTO "tablename"'
実装は簡単ですが、列に新しい行が含まれていると失敗します
SQLite挿入モード
for t in $(sqlite3 $DB .tables); do
echo -e ".mode insert $t\nselect * from $t;"
done | sqlite3 $DB > backup.sql
これは素敵でカスタマイズ可能なソリューションですが、空間に 'Geometry'タイプのようなblobオブジェクトがある場合は機能しません
スキーマでダンプを区別する
sqlite3 some.db .schema > schema.sql
sqlite3 some.db .dump > dump.sql
grep -v -f schema.sql dump > data.sql
理由はわかりませんが、私のために働いていません
おそらくこの質問に対する最良の答えはありませんが、私のために働いているのは、列の値の新しい行である このような式 を考慮して挿入をgrepすることです
grep -Pzo "(?s)^INSERT.*\);[ \t]*$"
テーブルを選択するには、ダンプする必要があります.dump
は、テーブル名と一致するLIKE引数を認めますが、これが十分でない場合は、おそらく単純なスクリプトの方が良いオプションです
TABLES='table1 table2 table3'
echo '' > /tmp/backup.sql
for t in $TABLES ; do
echo -e ".dump ${t}" | sqlite3 database.db3 | grep -Pzo "(?s)^INSERT.*?\);$" >> /tmp/backup.sql
done
または、外部キーを尊重し、すべてのダンプを1つのトランザクションのみでカプセル化するために、より精巧なもの
TABLES='table1 table2 table3'
echo 'BEGIN TRANSACTION;' > /tmp/backup.sql
echo '' >> /tmp/backup.sql
for t in $TABLES ; do
echo -e ".dump ${t}" | sqlite3 $1 | grep -Pzo "(?s)^INSERT.*?\);$" | grep -v -e 'PRAGMA foreign_keys=OFF;' -e 'BEGIN TRANSACTION;' -e 'COMMIT;' >> /tmp/backup.sql
done
echo '' >> /tmp/backup.sql
echo 'COMMIT;' >> /tmp/backup.sql
);
がいずれかの列に存在する文字列である場合、grep式が失敗することを考慮してください
復元するには(テーブルが既に作成されているデータベース内)
sqlite3 -bail database.db3 < /tmp/backup.sql
このバージョンは、挿入内の改行でうまく機能します。
sqlite3 database.sqlite3 .dump | grep -v '^CREATE'
実際には、改行を含む可能性が低いCREATE
で始まるすべての行を除外します
Retracileによる答えは最も近いはずですが、私の場合はうまくいきません。 1つの挿入クエリが途中で中断し、エクスポートが停止しました。理由はわかりません。ただし、.dump
中は正常に動作します。
最後に、.dump
から生成されたSQLを分割するためのツールを作成しました。