【问题标题】:Create SQL table from parquet files从 parquet 文件创建 SQL 表
【发布时间】:2020-11-06 04:09:09
【问题描述】:

我正在使用 R 处理大型数据集(最大数据帧 30.000.000 x 120)。这些文件作为 parquet 文件存储在 Azure Datalake Storage 中,我们需要每天查询这些文件并将它们还原到本地 SQL 数据库中。无需将数据加载到内存即可读取 Parquet 文件,这很方便。但是,从 parqueet 文件创建 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)

是否可以在不将 parquet 文件加载到内存的情况下编写 SQL 表?

【问题讨论】:

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


    【解决方案1】:

    我缺乏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 定义自定义文件格式,则可以指定它。

    现在上面只插入到现有表中。对于您希望从文件创建新表的特定情况,您可能会使用CREATE TABLE AS [select statement] 寻找更多OPENROWSET

    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 中的时间没有达到 BULK INSERT 或类似的。

    【讨论】:

    • 感谢@Oliver 的贡献!从这些替代方案中,BULK INSERT 似乎更直接。您是否知道应该使用 CREATE EXTERNAL FILE FORMAT 来使 BULK INSERT 正常工作?
    • 我很高兴至少能给你一个起点。我缺乏特定功能的经验(因为 IT 认为雪花对我们来说更好)。但简单地使用FORMAT = 'PARQUET' 可能会起作用。或者链接中的示例D(如果您单击我的答案中的查询)具有格式示例。在此之后,它可能就像使用 FORMAT = [name of the format you made] 一样简单。如果它不起作用,我认为下一个最佳选择是第二个。
    • 再次感谢,这很有帮助!似乎这两个选项目前都不是最佳选择,因为我有不支持创建外部文件格式的 SQL Server v12。
    • 在新创建的本地数据库上进行了一个小时的测试后,批量上传似乎也仅限于其 Azure 版本。 Sql server 确实总是有限制,具体取决于版本和计划。您最简单的解决方案可能是对 parquet 文件进行分区并从内存中上传每个分区,然后接受这需要时间。
    • 我担心它必须像你描述的那样做。我真的很感谢你的努力!如果有人稍后找到另一个可行的解决方案,我会保留票证。
    猜你喜欢
    • 2016-03-16
    • 1970-01-01
    • 2021-02-19
    • 2018-02-19
    • 2019-12-06
    • 1970-01-01
    • 1970-01-01
    • 2020-07-14
    相关资源
    最近更新 更多