Как автоматизировать процесс с помощью инструмента командной строки sqlite3.exe?
Я пытаюсь загрузить большую часть данных (5.5 миллионов строк) в файл базы данных SQLite.
Загрузка через INSERT кажется слишком медленной, поэтому я пытаюсь использовать инструмент командной строки sqlite3 и команду .import.
Он отлично работает, если я вхожу в команды вручную, но я не могу на всю жизнь решить, как автоматизировать его из script (.bat файла или python script; я работаю над Windows-машина).
Команды, которые я выдаю в командной строке, следующие:
> sqlite3 database.db
sqlite> CREATE TABLE log_entry ( <snip> );
sqlite> .separator "\t"
sqlite> .import logfile.log log_entry
Но ничего, что я попробую, заставит это работать из файла bat или python script.
Я пробовал такие вещи, как:
sqlite3 "database.db" .separator "\t" .import logfile.log log_entry
echo '.separator "\t" .import logfile.log log_entry' | sqlite3 database.db
Неужели я могу это сделать?
Ответы
Ответ 1
Создайте текстовый файл с строками, которые вы хотите ввести в программу командной строки sqlite, например:
CREATE TABLE log_entry ( );
.separator "\t"
.import logfile.log log_entry
а затем просто вызовите sqlite3 database.db < commands.txt
Ответ 2
В качестве альтернативы вы можете поместить все в один файл оболочки script (тем самым упростив обслуживание) с помощью heredoc import.sh:
#!/bin/bash --
sqlite3 -batch $1 <<"EOF"
CREATE TABLE log_entry ( <snip> );
.separator "\t"
.import logfile.log log_entry
EOF
... и запустите его:
import.sh database.db
Это упрощает сохранение только одного файла script.
Кстати, если вам нужно запустить его под Windows, Power Shell также имеет функцию heredoc
Кроме того, этот подход помогает справиться с отсутствием поддержки параметров script. Вы можете использовать переменные bash:
#!/bin/bash --
table_name=log_entry
sqlite3 -batch $1 <<EOF
CREATE TABLE ${table_name} ( <snip> );
.separator "\t"
.import logfile.log ${table_name}
EOF
Или даже сделайте такой трюк:
#!/bin/bash --
table_name=$2
sqlite3 -batch $1 <<EOF
CREATE TABLE ${table_name} ( <snip> );
.separator "\t"
.import logfile.log ${table_name}
EOF
... и запустите его: import.sh database.db log_entry
Ответ 3
Создайте отдельный текстовый файл, содержащий все команды, которые вы обычно вводите в приложение оболочки sqlite3:
CREATE TABLE log_entry ( <snip> );
.separator "\t"
.import /path/to/logfile.log log_entry
Сохраните его как, скажем, impscript.sql.
Создайте пакетный файл, который вызывает оболочку sqlite3 с этим script:
sqlite3.exe yourdatabase.db < /path/to/impscript.sql
Вызов командного файла.
На стороне примечания - при импорте обязательно заверните INSERT в транзакции! Это даст вам мгновенное ускорение 10.000%.
Ответ 4
Недавно я столкнулся с подобной проблемой при преобразовании файла cookie Firefox cookie.sqlite в текстовый файл (для некоторого инструмента для загрузки) и наткнулся на этот вопрос.
Я хотел сделать это с помощью одной строки оболочки, и это было бы моим решением, применяемым к вышеупомянутой проблеме:
echo -e ".mode tabs\n.import logfile.log log_entry" | sqlite3 database.db
Но я еще не тестировал эту строку. Но он отлично справился с проблемой Firefox, о которой я упоминал выше (кстати, через Bash в Mac OSX):
echo -e ".mode tabs\nselect host, case when host glob '.*' then 'TRUE' else 'FALSE' end, path, case when isSecure then 'TRUE' else 'FALSE' end, expiry, name, value from moz_cookies;" | sqlite3 cookies.sqlite
Ответ 5
sqlite3 abc.db ".read scriptname.sql"
Ответ 6
В этот момент я не уверен, что еще я могу добавить, кроме, у меня возникли проблемы с добавлением переменной среды unix в bash script, предлагаемой nad2000.
выполняется следующее:
bash dbmake.sh database.db <(sed '1d' $DATA/logfile.log | head -n 1000)
Мне нужно было импортировать из stdin в качестве обходного пути, и я нашел это решение:
sqlite3 $1 <<"EOF"
CREATE TABLE log_entry;
EOF
sqlite3 -separator $'\t' $1 ".import $2 log_entry"
Добавив вторую строку sqlite3, я смог передать $2 из Unix в параметр файла для .import, полного пути и всего.
Ответ 7
В Windows это должно работать:
(echo CREATE TABLE log_entry ( <snip> ); & echo .separator "\t" & echo .import logfile.log log_entry) | sqlite3.exe database.db
Я не тестировал эту конкретную команду, но из своего собственного решения решить эту проблему из нескольких команд, я обнаружил, что ключ должен заключать эхо-команды в круглые скобки. При этом возможно, что вам может понадобиться настроить вышеупомянутую команду, чтобы также избежать некоторых из этих символов. Например:
(echo CREATE TABLE log_entry ^( ^<snip^> ^); & echo .separator "\t" & echo .import logfile.log log_entry) | sqlite3.exe database.db
Я не уверен, что в этом случае требуется экранирование, но это очень вероятно, поскольку круглые скобки могут конфликтовать с окружающими, тогда символы "меньше" и "больше" обычно интерпретируются как входные или которые могут также конфликтовать. Подробный список побегов символов можно найти здесь: http://www.robvanderwoude.com/escapechars.php
Ответ 8
here trans is table name and trans.csv is a csv file in which i have 1959 rows of data
$ sqlite3 abc.db ".separator ','"
$ sqlite3 abc.db ".import 'trans.csv' trans"
$ sqlite3 abc.db "select count(*) from trans;"
1959
но его невозможно написать так, как вы писали