将CSV导入Sqlite

时间:2015-08-05 01:53:37

标签: sql shell unix sqlite

我的问题很简单。想象一下,您在CSV中有以下数据:

Name, Age, Gender
Jake, 40, M
Bill, 17, M
Suzie, 21, F

导入上述CSV时是否可以排除Age变量?我目前的方法是简单地使用cut shell命令。

更新

iluvcapra对小型CSV有很好的答案。但是,对于非常大的CSV,这种方法效率很低。例如,假设上面的CSV非常大,30Gb可以说。仅加载所有Age数据以立即删除是浪费时间。考虑到这一点,是否有更有效的方法将列子集加载到sqlite数据库?

我怀疑最好的选择是使用shell命令cut来剔除不必要的列。这种直觉是否正确?使用shell命令将CSV文件预处理成更多sqlite友好版本是否常见?

谢谢!

2 个答案:

答案 0 :(得分:5)

使用age列创建一个临时表,然后使用INSERT ... SELECT将数据从临时表移动到主表中:

CREATE TEMP TABLE _csv_import (name text, age integer, gender text);
.separator ","
.import file.csv test

INSERT INTO names_genders (name, gender) SELECT name, gender
    FROM _csv_import WHERE 1;
DROP TABLE _csv_import;

编辑:使用幻像年龄栏更新到视图中:

CREATE VIEW names_ages_genders AS 
    SELECT (name, 0 AS age ,gender) FROM names_genders;
CREATE TRIGGER lose_age
    INSTEAD OF INSERT ON names_ages_genders
    BEGIN
        INSERT INTO names_genders (name, gender) 
            VALUES (NEW.name, NEW.gender)
    END;

这将创建一个名为names_ages_genders的视图,该视图会说每个人都是零岁,并且会默默地从调用它的任何INSERT语句中删除age字段。没测试过! (我实际上不确定.import是否可以导入视图。)

答案 1 :(得分:1)

如果您希望避免对SQLite进行不必要的阅读,并且希望避免对CSV文件使用标准文本处理工具(例如cutawk)的危害,请使用可能会按照以下几行使用您最喜欢的csv2tsv转换器(*):

csv2tsv input.csv | cut -f 1,3- > tmp.tsv

cat << EOF | sqlite3 demo.db
drop table if exists demo;
.mode csv
.separator "\t"
.import tmp.tsv demo
EOF

/bin/rm tmp.tsv

但是请注意,如果input.csv具有文字制表符或换行符或转义的双引号,则  上面的效果是否会取决于所使用的csv2tsv。

(*)csv2tsv

如果您没有准备好访问合适的csv2tsv转换器,下面是一个简单的python3脚本,它可以完成此工作,处理嵌入的文字换行符,制表符以及两个字符的序列"\t"和{{ 1}},在CSV中:

"\n"