如何在SPARK 2.2.0中将外部表转换为托管表?

ous*_*dey 6 apache-spark

以下命令已成功将外部表转换为中的托管表Spark 2.0.0

ALTER TABLE {table_name} SET TBLPROPERTIES(EXTERNAL=FLASE);
Run Code Online (Sandbox Code Playgroud)

但是,上面的命令失败Spark 2.2.0并显示以下错误:

查询错误:无法设置或更改保留的属性键:'EXTERNAL';

sha*_*ala 6

正如 @AndyBrown 在评论中指出的那样,您可以选择转到控制台并在那里调用 Hive 语句。在 Scala 中,这对我有用:

import sys.process._
val exitCode = Seq("hive", "-e", "ALTER TABLE {table_name} SET TBLPROPERTIES(\"EXTERNAL\"=\"FALSE\")").!
Run Code Online (Sandbox Code Playgroud)

我使用 Spark 2.1.1 遇到了这个问题,其中 @Joha 的答案不起作用,因为由于被声明为惰性而无法访问 Spark.sessionState 。


Joh*_*oha 5

在 Spark 2.2.0 中,您可以执行以下操作:

import org.apache.spark.sql.catalyst.TableIdentifier
import org.apache.spark.sql.catalyst.catalog.CatalogTable
import org.apache.spark.sql.catalyst.catalog.CatalogTableType

val identifier = TableIdentifier("table", Some("database"))
val oldTable = spark.sessionState.catalog.getTableMetadata(identifier)
val newTableType = CatalogTableType.MANAGED 

val alteredTable = oldTable.copy(tableType = newTableType)

spark.sessionState.catalog.alterTable(alteredTable)
Run Code Online (Sandbox Code Playgroud)


小智 1

该问题是 Spark-2.1 及更高版本上的大小写敏感问题。

请尝试将 TBLPROPERTIES 设置为小写 -

    ALTER TABLE <TABLE NAME> SET TBLPROPERTIES('external'='false')
Run Code Online (Sandbox Code Playgroud)

  • 尽管您已经更正了 false 的引用和拼写,但将其设置为小写只是将用户属性“external”设置为“false”,并将保留的属性“EXTERNAL”保留为“TRUE”(并保留表的外部状态)。您可以通过运行“DESCRIBE FORMATTED &lt;tablename&gt;”来查看这一点。我和OP有同样的问题,无法解决它(如果我找到一个,我会发布并回答),但这不是答案。 (8认同)
  • @AndyBrown您是否找到了如何解决 set external = false 。我收到错误,正如您所描述的 org.apache.spark.sql.AnalysisException: 无法设置或更改保留的属性键: 'EXTERNAL'; (2认同)
  • @Donald 之类的。我找到了一个针对我的用例的解决方法,我认为它不是这个问题的合适答案:因为我在 pyspark 中操作,所以我进入 shell 并直接调用 hive 引擎来执行 SET 命令,它有效,因为错误仅发生在 Spark 上下文中。如果您认为这可能有用,很乐意在聊天中进行阐述。 (2认同)