【问题标题】:Loading multiple CSV files with SQLite使用 SQLite 加载多个 CSV 文件
【发布时间】:2022-05-02 17:11:39
【问题描述】:

我正在使用 SQLite,我需要将数百个 CSV 文件加载到一个表中。我没有设法在网上找到这样的东西。有可能吗?

请注意,一开始我使用的是 Oracle,但由于 Oracle 每个表有 1000 列的限制,而且我的 CSV 文件每个都有超过 1500 列,所以我不得不寻找另一种解决方案。我不想尝试 SQLite,因为我可以快速轻松地安装它。 这些 CSV 文件已经提供了诸如列数量之类的内容,我无法更改或拆分它们(不管为什么)。

请指教。

【问题讨论】:

  • 所有 CSV 文件是否都进入同一个表?如果是这样,您可以执行 cat *.csv > big.csv 并加载 big.csv
  • 是的。有些文件大于 1GB。将这么多大文件合并到一个文件中将创建一个巨大的文件。恐怕它会以某种方式出现问题......
  • 如果您的系统无法处理多 GB 的 CSV 文件,那么它将会在处理多 GB 的数据库时出现问题。
  • 目前还不清楚,至少对我来说,您的问题是您根本不知道如何将单个 CSV 文件加载到 SQLite 中,或者问题是您不知道如何处理数百个文件。
  • 问题是我不知道如何处理数百个文件。

标签: sqlite csv


【解决方案1】:

我遇到了类似的问题,你的问题的 cmets 实际上给了我最终对我有用的答案

第 1 步:将多个 csv 合并到一个文件中。排除其中大多数的标题,但在开头写下其中一个的标题。

第 2 步:将单个合并的 csv 加载到 SQLite。

对于第 1 步,我使用了:

$ head -1 one.csv > all_combined.csv
$ tail -n +2 -q *.csv >> all_combined.csv

第一个命令只写入 csv 文件的第一行(您可以选择任何一个文件),第二个命令从第 2 行开始写入整个文档,因此不包括标题。 -q 选项确保tail 永远不会将文件名写入标题。

确保将all_combined.csv 放在单独的文件夹中,否则在某些发行版中,它将被递归包含!

要加载到 SQLite(第 2 步)中,Hot Licks 给出的答案对我有用:

 sqlite> .mode csv
 sqlite> .import all_combined.csv my_new_table

这假定my_new_table 尚未创建。或者,您可以预先创建然后加载,但在这种情况下,请从步骤 1 中排除标题。

【讨论】:

  • 我不确定为什么,但这里的第 1 步使all_combined.csv 在我的 Ubuntu 20.04 上递归增长,直到我用完磁盘空间。使用不同的扩展程序或将其存储在不同的文件夹中可以解决问题。
【解决方案2】:

http://www.sqlite.org/cli.html --

使用“.import”命令将 CSV(逗号分隔值)数据导入 SQLite 表。 “.import”命令有两个参数,分别是要从中读取 CSV 数据的磁盘文件的名称和要插入 CSV 数据的 SQLite 表的名称。

请注意,在运行“.import”命令之前将“mode”设置为“csv”很重要。这对于防止命令行 shell 尝试将输入文件文本解释为其他格式是必要的。

sqlite> .mode csv
sqlite> .import C:/work/somedata.csv tab1

有两种情况需要考虑:(1) 表“tab1”以前不存在,(2) 表“tab1”已经存在。

在第一种情况下,当表以前不存在时,会自动创建表,并使用输入 CSV 文件的第一行的内容来确定表中所有列的名称。换句话说,如果该表以前不存在,则 CSV 文件的第一行被解释为列名,实际数据从 CSV 文件的第二行开始。

对于第二种情况,当表已经存在时,CSV 文件的每一行,包括第一行,都被假定为实际内容。如果 CSV 文件包含列标签的初始行,则该行将作为数据读取并插入到表中。为避免这种情况,请确保该表以前不存在。


请注意,您需要确保文件没有定义字段名称的初始行。而且,对于“数百个”文件,您可能需要准备一个脚本,而不是单独输入每个文件。

【讨论】:

  • 可以在您的答案的链接中阅读,名为“导入 CSV 文件”的部分(实际上是第 7.5 节,也许这已经及时改变了,或者可以做到):如果 CSV文件包含列标签的初始行,您可以使 .import 命令使用“--skip 1”选项跳过该初始行。
【解决方案3】:

我没有找到更好的方法来解决这个问题,所以我使用 findxargs 来避免创建一个巨大的中间 .csv 文件:

find . -type f -name '*.csv' | xargs -I% sqlite3 database.db ".mode csv" ".import % new_table" ".exit"

find 打印出文件名,xargs-I% 参数导致其后的命令每行运行一次,% 被替换为 csv 文件的名称。

【讨论】:

    猜你喜欢
    • 2010-09-18
    • 2017-03-18
    • 2019-04-09
    • 2021-05-26
    • 1970-01-01
    • 2014-03-20
    • 1970-01-01
    • 1970-01-01
    • 2019-10-23
    相关资源
    最近更新 更多