我正在开发 Azure Databricks,Databricks 运行时版本是 -
14.3 LTS (includes Apache Spark 3.5.0, Scala 2.12)
。我面临以下问题。
假设我有一个名为
v1
的视图和一个通过以下命令创建的数据库 f1_processed
。
CREATE DATABASE IF NOT EXISTS f1_processed
LOCATION "abfss://[email protected]/"
然后,如果我尝试使用以下命令在已存在的位置创建表。
CREATE TABLE f1_processed.circuits
AS
SELECT * FROM v1;
我收到以下错误
[DELTA_CREATE_TABLE_WITH_NON_EMPTY_LOCATION] Cannot create table ('`spark_catalog`.`f1_processed`.`circuits`').
The associated location ('abfss://[email protected]/circuits')
is not empty and also not a Delta table. SQLSTATE: 42601
但是,如果我将 CREATE 替换为 CREATE OR REPLACE,则该命令运行正常。所以下面的代码运行良好。
CREATE OR REPLACE TABLE f1_processed.circuits
AS
SELECT * FROM v1;
该表以前不存在。所以
CREATE OR REPLACE
基本上也是在创建一个表格。该行为不应该与 CREATE
命令一致吗?这是一个错误吗?任何帮助表示赞赏
CREATE TABLE
命令:在 CREATE TABLE
命令中,Apache Spark(以及扩展的 Databricks)期望为表指定的位置为空,除非该表已作为 Delta 表存在。这样做的目的是为了防止覆盖现有数据而导致数据意外丢失。如果该位置包含任何文件(即使从技术上讲元存储中不存在表)Spark 将抛出错误以防止潜在的意外覆盖。
CREATE OR REPLACE TABLE
命令:这在处理现有数据方面更加宽松。当您使用 CREATE OR REPLACE TABLE
时,意味着您意识到指定位置可能存在数据,并且有意选择覆盖它。如果该表存在,它将被该命令创建的新表替换(架构和数据)。如果该表不存在,则会创建该表。此命令用于以下场景:您希望确保存在具有特定模式的表,并替换该表的任何先前版本。
乍一看似乎不一致,但这种行为是故意的:
CREATE TABLE
:防止数据意外覆盖。CREATE OR REPLACE TABLE
的灵活性:允许幂等操作,您可能正在运行需要确保表存在具有特定架构的脚本,可能会在无需手动干预的情况下替换旧架构或数据。创建新表时使用
CREATE TABLE
:如果您确定该位置是新的或空的,并且想要防止意外覆盖,请使用 CREATE TABLE
命令。
使用
CREATE OR REPLACE TABLE
进行幂等操作:当您的脚本或操作需要确保存在具有来自视图或另一个表的最新架构或数据的表,并且您可以替换任何现有数据时,请使用 CREATE OR REPLACE TABLE
.
创建前检查:如果您以编程方式管理表并且想要格外小心,则可以在决定使用哪个命令之前检查表是否存在或位置是否为空。