我的问题很简单。想象一下,您在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友好版本是否常见?
谢谢!
答案 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文件使用标准文本处理工具(例如cut
和awk
)的危害,请使用可能会按照以下几行使用您最喜欢的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转换器,下面是一个简单的python3脚本,它可以完成此工作,处理嵌入的文字换行符,制表符以及两个字符的序列"\t"
和{{ 1}},在CSV中:
"\n"