使用 RSQLite 导入 csv 文件时如何忽略引号字符串中的定界符?

How to ignore delimiters inside quoted strings when importing a csv file with RSQLite?

我想导入一个与以下示例具有相似结构的 csv 文件:

var1;var2;var3
"a";1;"Some text"
"b";0;"More text"
"c;0;"Delimiter in ; middle of the text"

传统解析器(例如 data.table::fread 使用的解析器)默认处理该问题。我想使用 RSQLite::dbWriteTable 将此数据导入 SQLite 数据库。

con <- DBI::dbConnect(RSQLite::SQLite(), dbname = "mydb.sqlite")
dbWriteTable(conn = con, name = "my_table", value = "data_file.csv")

dbWriteTable 中没有提供引号的选项,因此当找到有问题的行时该函数会抛出错误。我如何导入这些数据?我唯一的限制是在导入到 SQLite 之前,我没有足够的内存来使用 R 解析数据。

安装 Windows 和 Linux 平台上可用的 csvfix 实用程序,然后尝试此测试代码。它在 Windows 对我有用。您可能需要为其他平台稍微调整它,特别是 shell 行和 eol= 参数,您可能不需要它们或者您可能需要不同的值。我们使用 csvfix 删除引号并将不在字段中的分号替换为 @。然后我们在读入的时候使用@分隔符。

首先我们创建测试数据。

# if (file.exists("mydb")) file.remove("mydb")
# if (file.exists("data_file2.csv")) file.remove("data_file2.csv")

# write out test file
cat('var1;var2;var3\n"a";1;"Some text"\n"b";0;"More text"\n"c";0;"Delimiter in ; middle of the text"', file = "data_file.csv")

# create database (can omit if it exists)
cat(file = "mydb")

csvfix

现在使用 csvfix 处理数据文件

library(RSQLite)

# preprocess file using csvfix - modify next line as needed depending on platform
shell("csvfix write_dsv -sep ; -s @ data_file.csv > data_file2.csv")
file.show("data_file2.csv") # omit this line for real data

# write file to database
con <- dbConnect(SQLite(), "mydb")
dbWriteTable(con, "myFile", "data_file2.csv", sep = "@", eol = "\r\n")
dbGetQuery(con, "select * from myFile") # omit this line for real data
dbDisconnect(con)

xsv

或者安装 xsv rust 实用程序。这对我有用Windows。

library(RSQLite)

shell("xsv fmt -d ; -t @ data_file.csv > data_file2.csv")
file.show("data_file2.csv") # omit this line for real data

# write file to database
con <- dbConnect(SQLite(), "mydb")
dbWriteTable(con, "myFile", "data_file2.csv", sep = "@")
dbGetQuery(con, "select * from myFile") # omit this line for real data
dbDisconnect(con)