在命令行或批处理文件中将 CSV 文件导入 Sqlite3 数据库

问题描述 投票:0回答:7

我想问一下是否有将包含我在 SQLite3 中的 select 语句输出的 csv 文件导入到新数据库中? 以下是我到目前为止所做的代码:

sqlite3.exe -csv logsql.sqlite "SELECT local_port AS port, COUNT(local_port) AS hitcount FROM connections  WHERE connection_type = 'accept' GROUP BY local_port ORDER BY hitcount DESC;" > output.csv
sqlite3.exe -csv test.sqlite "CREATE TABLE test (name varchar(255) not null, blah varchar(255) not null);" .import ./output.csv test

如您所见,我的第一个代码是转储所做的查询。

第二行代码我正在尝试创建一个新数据库并尝试将 csv 文件导入表“test”

感谢您提前提供的任何帮助! :D

windows csv batch-file import sqlite
7个回答
14
投票

我建议您从一个平面文件进行导入,这将创建您的架构,然后进行实际导入:

像这样:

sqlite3.exe test.sqlite < import.sql

其中import.sql的内容是:

CREATE TABLE test (name varchar(255) not null, blah varchar(255) not null);
.separator ,
.import output.csv test

您可能没有考虑过的另一种方法是 ATTACH 命令。您可以附加一个新数据库,在其中创建表,然后导入到它的表中,这样您就没有导出到 CSV 然后重新解析的额外步骤。它可以来自 CREATE TABLE ... AS SELECT ... 查询或只是一个 INSERT.

所以基本上,你会运行(从你的 PHP 页面):

"ATTACH 'c:\directory\to\database\test.db' as TESTDB;"
"CREATE TABLE TESTDB.test AS SELECT local_port AS port, COUNT(local_port) AS hitcount FROM connections  WHERE connection_type = 'accept' GROUP BY local_port ORDER BY hitcount DESC;"

或:

"ATTACH 'c:\directory\to\database\test.db' as TESTDB;"
"CREATE TABLE TESTDB.test (name varchar(255) not null, blah varchar(255) not null);"
"IMPORT INTO TESTDB.test SELECT local_port AS port, COUNT(local_port) AS hitcount FROM connections  WHERE connection_type = 'accept' GROUP BY local_port ORDER BY hitcount DESC;"

9
投票

通过对我有用的 bash 导入文件的单文件命令:

sqlite3 inventory.sqlite.db << EOF
delete from audit;
.separator "\t"
.import audit-sorted-uniq.tsv audit
EOF

希望有帮助。


1
投票

对于大型 CSV 文件,使用

sqlite3
shell 的
.import
命令可能更有效,而不是在 Python 中解析文件并使用
sqlite3
模块插入行。它可以通过
os.system
(在 Linux、Unix 或 Mac OS X 上,或在 Windows 上的 Cygwin 上)完成:

cmd = '(echo .separator ,; echo .import ' + csv_file + ' ' + table + ')'
cmd += '| sqlite3 ' + db_name
os.system(cmd)

0
投票

你可以用 SQLite 命令 shell 和命令行开关做很多事情...... ...但我强烈建议您找到一种可在 Windows 上运行并且您感觉舒服的支持 SQLite 的脚本语言。

Perl 和Python 是两个极好的选择。两者都支持 SqlLite,都可免费用于 Windows。

两者都可以处理这个 - 以及许多其他类型的任务。


0
投票

首先,您需要正确的带有逗号分隔符和标题行的真实 csv 文件。 为此,我使用了 phpstorm 的转储工具。

将所有文件放入文件夹中。

打开cmd.exe

创建导入语句,其中 %~na 是不带扩展名的文件名作为表名

for /R %a in (*.csv) do @echo .import %~na.csv %~na >> import.txt

使用虚拟数据库启动 sqlite

sqlite test.sqlite

设置导入模式为csv

.mode csv

从文件运行命令

.read import.txt

列出所有表

.tables

退出sqlite

.q

0
投票

我发现最简单的方法是确保在 csv 文件中第一行是列的名称,值从第 2 行开始。

sqlite3 database.db ".import --csv --skip 1 /user/name/work/somedata.csv tab1"
  • 其中数据库是将创建表的数据库。
  • --skip 1 将使第一行被忽略。
  • schema 将基于第一行的值作为列的名称创建。
  • /user/name/... 是 csv 文件的路径(Linux 文件系统)
  • tab1 是正在创建的表的名称。

-1
投票

我需要导入许多 csv 文件,所以我编写了以下 python 脚本,它使用 csv 文件的第一行作为表的字段名称,从 csv 文件创建和加载 sqlite 表:

#!/usr/bin/env python
import sqlite3
from csv import DictReader

class SQLiteDB():
    def __init__(self, dbname=':memory:'):
        self.db=sqlite3.connect(dbname)

    def importFromCSV(self, csvfilename, tablename, separator=","):
        with open(csvfilename, 'r') as fh:
            dr = DictReader(fh, delimiter=separator)
            fieldlist=",".join(dr.fieldnames)
            ph=("?,"*len(dr.fieldnames))[:-1]
            self.db.execute("DROP TABLE IF EXISTS %s"%tablename)
            self.db.execute("CREATE TABLE %s(%s)"%(tablename, fieldlist))
            ins="insert into %s (%s) values (%s)"%(tablename, fieldlist, ph)
            for line in dr:
                v=[]
                for k in dr.fieldnames: v.append(line[k])
                self.db.execute(ins, v)
        self.db.commit()

if __name__ == '__main__':
    db=SQLiteDB("mydatabase.sqlite")
    db.importFromCSV("mydata.csv", "mytable")

对于大量数据的导入,应该实现事务。

hth

© www.soinside.com 2019 - 2024. All rights reserved.