从实木复合地板文件创建SQL表

时间:2020-07-16 13:12:38

标签: sql r sql-server apache-spark parquet

我正在使用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表?

1 个答案:

答案 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数据类型到的完整转换(请注意,两个非常必要的转换:DatePOSIXlt不存在)。再次声明:我在T-sql中的时间没有花到批量插入或类似操作。