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

时间:2009-03-18 22:16:08

标签: sqlite scripting batch-file

我正在尝试将大量数据(550万行)批量加载到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 个答案:

答案 0 :(得分:52)

创建一个文本文件,其中包含您要在sqlite命令行程序中输入的行,如下所示:

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

然后只需致电sqlite3 database.db < commands.txt

答案 1 :(得分:25)

或者,您可以使用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 also features 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

答案 2 :(得分:17)

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

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

将其保存为impscript.sql。

创建一个批处理文件,该文件使用该脚本调用sqlite3 shell:

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

调用批处理文件。

旁注 - 导入时,确保将INSERT包装在事务中!这将使您立即获得10.000%的加速。

答案 3 :(得分:5)

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

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

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

但我还没有测试过那条线。但是我在上面提到的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

答案 4 :(得分:2)

sqlite3 abc.db ".read scriptname.sql"

答案 5 :(得分:1)

此时,我不确定除了之外我还能添加什么,我在向nad2000建议的bash脚本添加unix环境变量时遇到了一些麻烦。

运行这个:

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中的$ 2传递给.import,完整路径和所有内容的文件参数。

答案 6 :(得分:0)

在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

答案 7 :(得分:-1)

   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

但不可能像你写的那样写作