我正在使用R处理大型数据集(最大数据框30.000.000 x 120)。它们作为拼合文件存储在Azure Datalake存储中,我们需要每天查询这些文件并将它们还原到本地SQL数据库中。可以读取镶木地板文件,而无需将数据加载到内存中,这非常方便。但是,从parquuet文件创建SQL表更具挑战性,因为我不想将数据加载到内存中。
这是我使用的代码。不幸的是,这不是一个完美的代表,因为需要使用SQL数据库才能使其正常工作。
# load packages
library(tidyverse)
library(arrow)
library(sparklyr)
library(DBI)
# Create test data
test <- data.frame(matrix(rnorm(20), nrow=10))
# Save as parquet file
write_parquet(test2, tempfile(fileext = ".parquet"))
# Load main table
sc <- spark_connect(master = "local", spark_home = spark_home_dir())
test <- spark_read_parquet(sc, name = "test_main", path = "/tmp/RtmpeJBgyB/file2b5f4764e153.parquet", memory = FALSE, overwrite = TRUE)
# Save into SQL table
DBI::dbWriteTable(conn = connection,
name = DBI::Id(schema = "schema", table = "table"),
value = test)
是否可以在不将镶木地板文件加载到内存的情况下编写SQL表?
答案 0 :(得分:2)
我缺乏T-sql
批量导入和导出的经验,但是很可能会找到答案。
library(arrow)
library(DBI)
test <- data.frame(matrix(rnorm(20), nrow=10))
f <- tempfile(fileext = '.parquet')
write_parquet(test2, f)
#Upload table using bulk insert
dbExecute(connection,
paste("
BULK INSERT [database].[schema].[table]
FROM '", gsub('\\\\', '/', f), "' FORMAT = 'PARQUET';
")
)
这里我使用T-sql
自己的bulk insert
命令。
免责声明 我尚未在T-sql
中使用此命令,因此它可能充满错误。例如,我看不到在文档中指定快速压缩的位置,尽管可以使用CREATE EXTERNAL FILE FORMAT
定义自定义文件格式来指定它。
现在,以上内容仅插入到现有表中。对于您的特定情况,您想从文件中创建新表,则可能会使用OPENROWSET
寻找CREATE TABLE AS [select statement]
。
column_definition <- paste(names(column_defs), column_defs, collapse = ',')
dbExecute(connection,
paste0("CREATE TABLE MySqlTable
AS
SELECT *
FROM
OPENROWSET(
BULK '", f, "' FORMAT = 'PARQUET'
) WITH (
", paste0([Column definitions], ..., collapse = ', '), "
);
")
其中column_defs
是一个命名列表或向量,用于描述为每一列提供SQL数据类型的定义。 T-sql documentation page上提供了(或多或少)从R数据类型到的完整转换(请注意,两个非常必要的转换:Date
和POSIXlt
不存在)。再次声明:我在T-sql中的时间没有花到批量插入或类似操作。