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

2admgd59  于 2023-04-12  发布在  SQLite
关注(0)|答案(7)|浏览(253)

我想问一下,是否有办法将包含我在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

z8dt9xmd

z8dt9xmd1#

我建议从平面文件进行导入,这将创建您的模式,然后进行实际导入:
就像这样:

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;"
niwlg2el

niwlg2el2#

一个通过bash导入文件的单文件命令对我很有效:

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

希望能帮上忙。

1hdlvixo

1hdlvixo3#

对于大型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)
idfiyjo8

idfiyjo84#

你可以用SQLite命令shell和命令行开关做很多事情……但我强烈建议你找到一种能在Windows上工作的、你觉得舒服的、支持SQLite的脚本语言。
Perl和Python是两个很好的选择。两者都支持SqlLite,都可以在Windows上免费获得。
两者都可以处理这个-以及许多其他类型的任务。

nnvyjq4y

nnvyjq4y5#

首先,你需要正确的真实的的csv文件与逗号分隔符和标题行。我使用了转储工具从phpstorm的这一点。
把所有文件放到一个文件夹里。

打开cmd.exe
创建import语句,其中%~na是文件名,不带扩展名tablename

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
pkbketx9

pkbketx96#

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

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

qyyhg6bp7#

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

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

对于导入大量数据,应实现事务。
高温高压

相关问题