Spark ML_管道:管理表读取

Spark ML_管道:管理表读取,r,apache-spark,sparklyr,R,Apache Spark,Sparklyr,我正在使用SparkML_管道在生产环境中使用SCALA轻松部署我在SparkyR中开发的操作。它工作得很好,除了一个部分:当我从Hive读取一个表,然后创建一个将操作应用于该表的管道时,管道还将保存表读取操作,从而保存表的名称。然而,我希望管道独立于此 以下是一个可复制的示例: 零件: sc = spark2_context(memory = "4G") iris <- copy_to(sc, iris, overwrite=TRUE) spark_write_table(iris,

我正在使用Spark
ML_管道
在生产环境中使用
SCALA
轻松部署我在
SparkyR
中开发的操作。它工作得很好,除了一个部分:当我从
Hive
读取一个表,然后创建一个将操作应用于该表的管道时,管道还将保存表读取操作,从而保存表的名称。然而,我希望管道独立于此

以下是一个可复制的示例:

零件:

sc = spark2_context(memory = "4G")

iris <- copy_to(sc, iris, overwrite=TRUE)

spark_write_table(iris, "base.iris")
spark_write_table(iris, "base.iris2")
df1 <- tbl(sc, "base.iris")

df2 <- df1 %>%
  mutate(foo = 5)

pipeline <- ml_pipeline(sc) %>%
  ft_dplyr_transformer(df2) %>%
  ml_fit(df1)

ml_save(pipeline,
        paste0(save_pipeline_path, "test_pipeline_reading_from_table"),
        overwrite = TRUE)

df2 <- pipeline %>% ml_transform(df1)

dbSendQuery(sc, "drop table base.iris")
我得到这个错误:

org.apache.spark.sql.AnalysisException: Table or view not found: `base`.`iris`; line 2 pos 5;
'Project ['Sepal_Length, 'Sepal_Width, 'Petal_Length, 'Petal_Width, 'Species, 5.0 AS foo#110]
+- 'UnresolvedRelation `base`.`iris`

  at org.apache.spark.sql.catalyst.analysis.package$AnalysisErrorAt.failAnalysis(package.scala:42)
  at org.apache.spark.sql.catalyst.analysis.CheckAnalysis$$anonfun$checkAnalysis$1.apply(CheckAnalysis.scala:82)
  at org.apache.spark.sql.catalyst.analysis.CheckAnalysis$$anonfun$checkAnalysis$1.apply(CheckAnalysis.scala:78)
  at org.apache.spark.sql.catalyst.trees.TreeNode.foreachUp(TreeNode.scala:127)
  at org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$foreachUp$1.apply(TreeNode.scala:126)
  at org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$foreachUp$1.apply(TreeNode.scala:126)
  at scala.collection.immutable.List.foreach(List.scala:381)
  at org.apache.spark.sql.catalyst.trees.TreeNode.foreachUp(TreeNode.scala:126)
  at org.apache.spark.sql.catalyst.analysis.CheckAnalysis$class.checkAnalysis(CheckAnalysis.scala:78)
  at org.apache.spark.sql.catalyst.analysis.Analyzer.checkAnalysis(Analyzer.scala:91)
  at org.apache.spark.sql.execution.QueryExecution.assertAnalyzed(QueryExecution.scala:52)
  at org.apache.spark.sql.Dataset$.ofRows(Dataset.scala:67)
  at org.apache.spark.sql.SparkSession.sql(SparkSession.scala:637)
  at org.apache.spark.ml.feature.SQLTransformer.transformSchema(SQLTransformer.scala:86)
  at org.apache.spark.ml.PipelineModel$$anonfun$transformSchema$5.apply(Pipeline.scala:310)
  at org.apache.spark.ml.PipelineModel$$anonfun$transformSchema$5.apply(Pipeline.scala:310)
  at scala.collection.IndexedSeqOptimized$class.foldl(IndexedSeqOptimized.scala:57)
  at scala.collection.IndexedSeqOptimized$class.foldLeft(IndexedSeqOptimized.scala:66)
  at scala.collection.mutable.ArrayOps$ofRef.foldLeft(ArrayOps.scala:186)
  at org.apache.spark.ml.PipelineModel.transformSchema(Pipeline.scala:310)
  at org.apache.spark.ml.PipelineStage.transformSchema(Pipeline.scala:74)
  at org.apache.spark.ml.PipelineModel.transform(Pipeline.scala:304)
  ... 71 elided
我可以看到两种解决方案:

  • 似乎持久化
    dataframe
    将是一个解决方案,但是我需要找到一种方法来避免内存过载,因此我的问题是

  • 将配置单元中表的名称作为管道的参数传递,我正试图在中解决这个问题

  • 现在,所有这些都说了,我可能错过了一些东西,因为我只是一个初学者

    编辑:这与标题中指定的集成刚刚在管道中读取的数据帧的具体问题有很大不同

    编辑:对于我的项目来说,在阅读表之后持久化它们是一个可行的解决方案。我不知道是否有更好的解决办法

    然后管道将我的表称为“base.table”,这使得它不可能应用于另一个表

    事实并非如此
    ft\u dplyr\u transformer
    是Spark自己的
    SQLTransformer
    的语法糖。内部
    dplyr
    (Spark占位符引用当前表)

    假设您有这样的转换:

    copy_to(sc、iris、overwrite=TRUE)
    df%
    突变(foo=5)
    管道%
    变压器(df)%>%
    ml_fit(待定(sc,“iris”))
    ml_stage(管道,“dplyr_transformer”)%%>%spark_jobj()%%>%invoke(“getStatement”)
    
    [1]“选择'Sepal\u Length'、'Sepal\u Width'、'Petal\u Length'、'Petal\u Width'、'Species',5.0作为'foo`\n来自此`”
    
    然而,这种表达方式相当混乱,直接使用本机SQL transformer更有意义:

    pipeline <- ml_pipeline(sc) %>%
      ft_sql_transformer("SELECT *, 5 as `foo` FROM __THIS__") %>%
      ml_fit(df)
    
    模式将是

    > pattern
    [1] "\\bdefault.iris\\b"
    
    但是,返回反向引用的完全限定名:

    > dbplyr::sql_render(x)
    <SQL> SELECT `Sepal_Length`, `Sepal_Width`, `Petal_Length`, `Petal_Width`, `Species`, 5.0 AS `foo`
    FROM `default`.`iris`
    
    dbplyr::sql\u render(x) 选择“萼片长度”、“萼片宽度”、“花瓣长度”、“花瓣宽度”、“种类”5.0作为“foo”` 从'default`.'iris`
    因此模式与名称不匹配

    > pattern
    [1] "\\bdefault.iris\\b"
    
    > dbplyr::sql_render(x)
    <SQL> SELECT `Sepal_Length`, `Sepal_Width`, `Petal_Length`, `Petal_Width`, `Species`, 5.0 AS `foo`
    FROM `default`.`iris`