Jak zautomatyzować proces za pomocą sqlite3.exe command line tool?

Próbuję zbiorczo załadować wiele danych (5,5 miliona wierszy) do pliku bazy danych SQLite. Ładowanie za pomocą wstawek wydaje się być zbyt wolne, więc próbuję użyć narzędzia wiersza poleceń sqlite3 i .polecenie Importuj.

Działa idealnie, jeśli wprowadzam polecenia ręcznie, ale nie mogę na całe życie wymyślić, jak zautomatyzować go ze skryptu ( .plik bat lub skrypt Pythona; pracuję na komputerze z systemem Windows).

Polecenia, które wydaję w wierszu poleceń są te:

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

Ale nic, co spróbuję, nie uruchomi tego z pliku bat lub skryptu Pythona.

Próbowałem takich rzeczy jak:

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

echo '.separator "\t" .import logfile.log log_entry' | sqlite3 database.db
Na pewno mogę to jakoś zrobić?
Author: dave, 2009-03-19

8 answers

Utwórz plik tekstowy z wierszami, które chcesz wprowadzić do programu wiersza poleceń sqlite, TAK:

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

A następnie po prostu zadzwoń sqlite3 database.db < commands.txt

 50
Author: Joey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-18 22:29:16

Alternatywnie możesz umieścić wszystko w jednym pliku skryptu powłoki (upraszczając konserwację) za pomocą heredoc import.sh :

#!/bin/bash --
sqlite3 -batch $1 <<"EOF"
CREATE TABLE log_entry ( <snip> );
.separator "\t"
.import logfile.log log_entry
EOF

...i uruchom:

import.sh database.db

Ułatwia utrzymanie tylko jednego pliku skryptu. Przy okazji, jeśli chcesz go uruchomić pod Windows, Power Shell zawiera również heredoc

Ponadto takie podejście pomaga radzić sobie z brakiem obsługi parametrów skryptu. Możesz użyć zmiennych bash:

#!/bin/bash --

table_name=log_entry

sqlite3 -batch $1 <<EOF
CREATE TABLE ${table_name} ( <snip> );
.separator "\t"
.import logfile.log ${table_name}
EOF

Lub nawet zrobić trick like this:

#!/bin/bash --

table_name=$2

sqlite3 -batch $1 <<EOF
CREATE TABLE ${table_name} ( <snip> );
.separator "\t"
.import logfile.log ${table_name}
EOF

...i uruchom go: import.sh database.db log_entry

 24
Author: nad2000,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-18 16:53:30

Utwórz osobny plik tekstowy zawierający wszystkie polecenia, które normalnie wpisujesz do aplikacji powłoki sqlite3:

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

Zapisz to jako, powiedzmy, impscript.sql.

Utwórz plik wsadowy, który wywoła powłokę sqlite3 za pomocą tego skryptu:

sqlite3.exe yourdatabase.db < /path/to/impscript.sql
Wywołanie pliku wsadowego.

Na marginesie-przy imporcie, upewnij się, że wkładki są zawinięte w transakcję! To da Ci natychmiastowe 10.000% przyspieszenie.

 16
Author: Mihai Limbășan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-18 22:29:53

Niedawno miałem podobny problem podczas konwersji plików cookie Firefoksa.sqlite do pliku tekstowego (dla jakiegoś narzędzia do pobierania) i natknąłem się na to pytanie.

Chciałem to zrobić z pojedynczą linią powłoki i to byłoby moje rozwiązanie zastosowane do wyżej wymienionego problemu:

echo -e ".mode tabs\n.import logfile.log log_entry" | sqlite3 database.db
Ale jeszcze nie testowałem tej linii. Ale działało dobrze z problemem Firefoksa, o którym wspomniałem powyżej (btw via Bash na 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
Author: Pesthauch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-14 19:32:41
sqlite3 abc.db ".read scriptname.sql"
 2
Author: someone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-16 00:20:58

W tym momencie, Nie jestem pewien, co jeszcze mogę dodać inne niż, miałem pewne problemy z dodaniem zmiennej środowiskowej unix do skryptu bash sugerowane przez nad2000.

Running this:

bash dbmake.sh database.db <(sed '1d' $DATA/logfile.log | head -n 1000)

Musiałem zaimportować ze standardowego wejścia jako obejście i znalazłem takie rozwiązanie:

sqlite3 $1 <<"EOF"
CREATE TABLE log_entry;
EOF
sqlite3 -separator $'\t' $1 ".import $2 log_entry"

Dodając drugą linię sqlite3, udało mi się przekazać $2 z Uniksa do parametru file for .import, pełna ścieżka i wszystko.

 1
Author: jimh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-16 22:37:20

W systemie Windows powinno działać:

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

Nie testowałem tego konkretnego polecenia, ale z mojego własnego dążenia do rozwiązania problemu przesyłania wielu poleceń odkryłem, że kluczem jest umieszczenie Echo poleceń w nawiasach. Biorąc to pod uwagę, możliwe, że będziesz musiał dostosować powyższe polecenie, aby również uciec od niektórych z tych znaków. Na przykład:

(echo CREATE TABLE log_entry ^( ^<snip^> ^); & echo .separator "\t" & echo .import logfile.log log_entry) | sqlite3.exe database.db

Nie jestem pewien, czy ucieczka jest potrzebna w tym przypadku, ale jest to wysoce prawdopodobne, ponieważ w nawiasach symbole "less than " i "greater than " są zwykle interpretowane jako wejścia lub wyjścia, które również mogą być sprzeczne. Obszerną listę ucieczek postaci można znaleźć tutaj: http://www.robvanderwoude.com/escapechars.php

 0
Author: ner0,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-25 10:42:20
   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

Ale nie da się napisać tak jak napisałeś

 -1
Author: Bhargava,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-16 10:12:52