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

Posted

技术标签:

【中文标题】如何使用 sqlite3.exe 命令行工具自动化进程?【英文标题】:How to automate a process with the sqlite3.exe command line tool? 【发布时间】:2010-10-14 04:54:00 【问题描述】:

我正在尝试将大量数据(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

我肯定能做到这一点吗?

【问题讨论】:

通过 INSERT 加载的速度有多慢?我在 12 分钟内使用插入语句在 Sqlite 中插入了 1500 万行大行。您必须使用事务和准备好的语句。 非常慢。我正在使用 python 来解析日志文件并将每一行作为一行插入。我没有使用准备好的语句,但我正在使用事务。即便如此,使用 sqlite3 程序执行此操作要快得多 使用准备好的语句会产生巨大的差异。我可以在标准 PC 上使用 INSERT 在 12 分钟内创建一个 2 GB 的 sqlite 数据库(1 个带有 1 个索引的大表)。 @tuinstoel 您能否举例说明将 INSERT 准备好的语句或事务放置在 insert.sql 脚本sqlite3 test.db &lt; insert.sql 中的语法?这里 insert.sql 包含 CREATE TABLE log_entry ( &lt;snip&gt; ); .separator "\t" .import logfile.log log_entry 作为 OP 【参考方案1】:

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

创建表 log_entry ( ); . 分隔符“\t” .import logfile.log log_entry

然后拨打sqlite3 database.db &lt; commands.txt

【讨论】:

您的解决方案是正确的,我被卡住了,因为您在点之前不能有任何空格。脚本中的命令。仅供参考【参考方案2】:

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

【讨论】:

作者 - 提到他正在使用 Windows - 仅供参考【参考方案3】:

创建一个单独的文本文件,其中包含您通常会在 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% 的加速。

【讨论】:

【参考方案4】:

我最近在将 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

【讨论】:

我可以确认这个方法有效;刚刚在 OSX 上试了一下没问题。 作者 - 提到他正在使用 Windows - 仅供参考 windows下没有'echo -e'这样的命令。就像 ozmike 已经评论过的那样,作者说“我正在使用 Windows 机器”。【参考方案5】:
sqlite3 abc.db ".read scriptname.sql"

【讨论】:

欢迎来到 Stack Overflow!虽然此代码 sn-p 可以解决问题,包括解释 really helps 以提高您的帖子质量。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人!请edit您的答案添加解释,并说明适用的限制和假设。 感谢这个答案,尽管稀疏:) 在这里详细说明您的答案sqlitetutorial.net/sqlite-commands“要执行 commands.txt 文件中的 SQL 语句,请使用 .read FILENAME 命令”【参考方案6】:

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

运行这个:

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

我需要从标准输入导入作为解决方法,我找到了这个解决方案:

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

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

【讨论】:

【参考方案7】:

在 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

【讨论】:

【参考方案8】:
   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

但不可能像你写的那样写

【讨论】:

在运行多个 sqlite 进程时调用“.separator ','”无效,如上所示。

以上是关于如何使用 sqlite3.exe 命令行工具自动化进程?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 sqlite3.exe 从导出的 .sql 脚本创建数据库

SQLITE3.EXE批量执行点命令的方法

在 Windows 中使用命令行 shell 创建 sqlite 数据库

svn报错:privious operation has not finshed;run 'cleanup' if it was interrupted

Android--SQLite应用

zbb20171017 svn Cleanup failed to process the following paths错误的解决