programing

sqlite3.exe 명령 줄 도구로 프로세스를 자동화하는 방법은 무엇입니까?

minecode 2021. 1. 14. 08:10
반응형

sqlite3.exe 명령 줄 도구로 프로세스를 자동화하는 방법은 무엇입니까?


SQLite 데이터베이스 파일에 많은 데이터 (550 만 행)를 대량로드하려고합니다. INSERT를 통한 로딩이 너무 느려서 sqlite3 명령 줄 도구와 .import 명령을 사용하려고합니다.

수동으로 명령을 입력하면 완벽하게 작동하지만 스크립트 (.bat 파일 또는 python 스크립트, Windows 시스템에서 작업 중입니다)에서 자동화하는 방법을 알아낼 수는 없습니다.

명령 줄에서 실행하는 명령은 다음과 같습니다.

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

그러나 내가 시도하는 것은 박쥐 파일이나 파이썬 스크립트에서 작동하지 않습니다.

나는 다음과 같은 것을 시도 해왔다.

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

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

어떻게 든 할 수 있을까요?


다음과 같이 sqlite 명령 줄 프로그램에 입력 할 줄이있는 텍스트 파일을 만듭니다.

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

그리고 그냥 전화 sqlite3 database.db < commands.txt


또는 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


일반적으로 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

배치 파일을 호출합니다.

On a side note - when importing, make sure to wrap the INSERTs in a transaction! That will give you an instant 10.000% speedup.


I just recently had a similar problem while converting Firefox' cookies.sqlite to a text file (for some downloading tool) and stumbled across this question.

I wanted to do that with a single shell line and that would be my solution applied to the above mentioned problem:

echo -e ".mode tabs\n.import logfile.log log_entry" | sqlite3 database.db

But I haven't tested that line yet. But it worked fine with the Firefox problem I mentioned above (btw via Bash on 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

sqlite3 abc.db ".read scriptname.sql"

At this point, I'm not sure what else I can add other than, I had some trouble adding a unix environment variable to the bash script suggested by nad2000.

running this:

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

I needed to import from stdin as workaround and I found this solution:

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

By adding the second sqlite3 line, I was able to pass the $2 from Unix into the file parameter for .import, full path and everything.


On Windows, this should work:

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

I haven't tested this particular command but from my own pursuit of solving this issue of piping multiple commands I found that the key was to enclose the echoed commands within parentheses. That being said, it is possible that you may need to tweak the above command to also escape some of those characters. For example:

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

I'm not sure if the escaping is needed in this case, but it is highly probable since the parentheses may conflict with the enclosing ones, then the "less than" and "greater than" symbols are usually interpreted as input or output which may also conflict. An extensive list of characters' escape may be found here: http://www.robvanderwoude.com/escapechars.php


   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

but its impossible to write like as you wrote

ReferenceURL : https://stackoverflow.com/questions/660320/how-to-automate-a-process-with-the-sqlite3-exe-command-line-tool

반응형