Как автоматизировать процесс с помощью инструмента командной строки sqlite3.exe? - PullRequest
54 голосов
/ 19 марта 2009

Я пытаюсь выполнить массовую загрузку большого количества данных (5,5 миллиона строк) в файл базы данных SQLite. Загрузка через INSERT кажется слишком медленной, поэтому я пытаюсь использовать инструмент командной строки sqlite3 и команду .import.

Это прекрасно работает, если я ввожу команды вручную, но я не могу на всю жизнь понять, как автоматизировать его с помощью сценария (файл .bat или сценарий python; я работаю на компьютере с Windows) .

Команды, которые я запускаю в командной строке:

> sqlite3 database.db
sqlite> CREATE TABLE log_entry ( <snip> );
sqlite> .separator "\t"
sqlite> .import logfile.log log_entry

Но ничто из того, что я пробую, не заставит это работать из файла bat или скрипта python.

Я пробовал такие вещи, как:

sqlite3 "database.db" .separator "\t" .import logfile.log log_entry

echo '.separator "\t" .import logfile.log log_entry' | sqlite3 database.db

Конечно, я могу сделать это как-нибудь?

Ответы [ 8 ]

52 голосов
/ 19 марта 2009

Создайте текстовый файл со строками, которые вы хотите ввести в программу командной строки sqlite, например:

CREATE TABLE log_entry (  );
.separator "\t"
.import logfile.log log_entry

, а затем просто позвоните sqlite3 database.db < commands.txt

25 голосов
/ 17 декабря 2011

В качестве альтернативы вы можете поместить все в один файл сценария оболочки (что упрощает обслуживание), используя 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

Это упрощает поддержку только одного файла скрипта. Кстати, если вам нужно запустить его под Windows, Power Shell также имеет heredoc

Кроме того, этот подход помогает справиться с отсутствием поддержки параметров скрипта. Вы можете использовать переменные 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

17 голосов
/ 19 марта 2009

Создайте отдельный текстовый файл, содержащий все команды, которые вы обычно вводите в приложение оболочки sqlite3:

CREATE TABLE log_entry ( <snip> );
.separator "\t"
.import /path/to/logfile.log log_entry

Сохраните как, скажем, impscript.sql.

Создайте пакетный файл, который вызывает оболочку sqlite3 с этим сценарием:

sqlite3.exe yourdatabase.db < /path/to/impscript.sql

Вызовите пакетный файл.

На заметку - при импорте не забудьте обернуть вставки в транзакцию ! Это даст вам мгновенное ускорение на 10.000%.

5 голосов
/ 14 апреля 2012

У меня недавно была похожая проблема при преобразовании cookie.sqlite в Firefox в текстовый файл (для некоторого инструмента для загрузки), и я наткнулся на этот вопрос.

Я хотел сделать это с одной линией оболочки, и это было бы моим решением, примененным к вышеупомянутой проблеме:

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
2 голосов
/ 15 ноября 2016
sqlite3 abc.db ".read scriptname.sql"
1 голос
/ 17 декабря 2014

На данный момент я не уверен, что еще я могу добавить, кроме как, у меня возникли проблемы с добавлением переменной окружения unix в сценарий bash, предложенный 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, полного пути и всего.

0 голосов
/ 25 августа 2017

В 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

0 голосов
/ 16 июля 2011
   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

но невозможно написать так, как ты написал

...