如何使用sqlite3.exe命令行工具自动执行进程?

我试图将大量数据(550万行)批量加载到SQLite数据库文件中。 通过INSERT加载似乎太慢了,所以我试图使用sqlite3命令行工具和.import命令。

如果我手工input命令,它是完美的工作,但我不能为我的生活找出如何从脚本(.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 

当然,我可以做到这一点?

用你想inputsqlite命令行程序的行创build一个文本文件,如下所示:

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

然后调用sqlite3 database.db < commands.txt

或者,您可以使用heredoc import.sh将所有内容放在一个shell脚本文件中(从而简化维护):

 #!/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还具有heredocfunction

另外这种方法有助于处理缺乏脚本参数的支持。 你可以使用bashvariables:

 #!/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

创build一个单独的文本文件,其中包含您通常会在sqlite3 shell应用程序中input的所有命令:

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

把它保存为impscript.sql。

创build一个使用该脚本调用sqlite3 shell的batch file:

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

调用batch file。

在一个侧面说明 – 导入时, 确保将INSERTs包装在一个事务中 ! 这会让你瞬间提高10.000%。

我最近有一个类似的问题,同时将Firefox的cookies.sqlite转换为文本文件(对于某些下载工具),并偶然发现了这个问题。

我想用一个单一的shell行来做,这将是我的解决scheme应用于上述问题:

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

但是我还没有testing过那条线。 但它工作正常,我上面提到的Firefox问题(顺便说一句,在Mac OSX上通过Bash):

 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" 

在这一点上,我不知道还有什么可以补充,除了在nad2000提供的bash脚本中添加一个unix环境variables,我遇到了一些麻烦。

运行这个:

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

我需要从标准input作为解决方法,我发现这个解决scheme:

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

通过添加第二个sqlite3行,我能够将Unix中的$ 2传递给.import,完整path和所有内容的文件参数。

在Windows上,这应该工作:

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

我没有testing这个特定的命令,但从我自己的追求解决这个pipe道多个命令的问题我发现,关键是将括弧内的回显命令。 这就是说,你可能需要调整上面的命令来逃避一些这些字符。 例如:

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

在这种情况下,我不确定是否需要转义,但是由于括号可能与包含的转义相冲突,所以很有可能,那么“ 小于 ”和“ 大于 ”符号通常被解释为input或输出,也冲突。 可以在这里find一个广泛的人物逃生名单: 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 

但不可能像你写的那样写