Delta Lake를 사용하여 선택적으로 데이터 덮어쓰기

Delta Lake에는 선택적 덮어쓰기를 위한 다음과 같은 고유한 옵션이 있습니다.

Option 사용 사례 지원되는 컴퓨팅 유형 최소 버전
REPLACE WHERE 조건자와 일치하는 행을 원자적으로 덮어씁니다. 일치 조건이 고정된 대체(예: colA = 5 또는 int_col IN (1, 2, 3).)에 사용합니다. 모든 컴퓨팅 유형입니다. Databricks Runtime 12.2 LTS 이상에서의 SQL. Databricks Runtime 9.1 LTS 이상에서의 Python 및 Scala
REPLACE USING 동적 데이터 덮어쓰기 제공된 데이터 집합에서 열 값의 같음 비교에 따라 지정된 열과 일치하는 모든 행을 바꿉니다. 모든 컴퓨팅 유형입니다. Databricks Runtime 16.3 이상에서의 SQL. Databricks Runtime 18.2 이상에서의 Python 및 Scala
REPLACE ON 부울 식을 사용한 동적 데이터 덮어쓰기 복잡한 일치 조건 또는 NULL-안전 일치 조건(예: s.colA <=> t.colA AND s.colB <=> t.colB)으로 대체할 때 사용합니다. 모든 컴퓨팅 유형입니다. Databricks Runtime 17.1 이상에서의 SQL. Databricks Runtime 18.2 이상 버전의 Python 및 Scala
partitionOverwriteMode 쓰기 작업이 새 데이터를 커밋할 각 파티션의 기존 데이터를 모두 덮어쓰는 레거시 동적 파티션 덮어쓰기. 새 워크로드에는 권장되지 않습니다. SQL은 클래식 컴퓨팅만 지원합니다. Python 및 Scala는 모든 컴퓨팅 유형을 지원합니다. Databricks Runtime 11.3 LTS 이상에서 SQL, Python 및 Scala를 사용할 수 있습니다.

대부분의 사용 사례에서는 Databricks에서 REPLACE USING 또는 REPLACE WHERE를 사용하는 것을 권장합니다. 사용 사례에 복잡하거나 NULL로부터 안전한 일치 조건이 필요한 경우에만 사용합니다 REPLACE ON .

각 옵션의 대체 동작에 대한 자세한 내용은 다음을 참조하세요 INSERT. Delta Lake 옵션의 DataFrameWriter 전체 목록은 Delta Lake 및 Apache Iceberg를 참조하세요.

Scala 및 Python에서는 replaceOnreplaceUsingreplaceWhere, partitionOverwriteMode 또는 overwriteSchema와 함께 사용할 수 없습니다.

빈 원본 쿼리의 경우 REPLACE USINGREPLACE ON는 모두 데이터를 삭제하지 않지만, REPLACE WHERE는 데이터를 삭제할 수 있습니다.

Important

데이터가 실수로 덮어쓰여진 경우 복원 을 사용하여 변경 내용을 실행 취소할 수 있습니다.

REPLACE WHERE

임의 식과 일치하는 데이터만 선택적으로 덮어쓸 수 있습니다 REPLACE WHERE.

Important

REPLACE WHERE를 실행할 때 증분 새로 고침의 이점을 얻으려면 Spark Declarative Pipelines(SDP)에서 REPLACE WHERE 흐름을 사용하세요. REPLACE WHERE 흐름을 사용한 Batch 처리를 참조하세요.

start_date로 분할된 대상 테이블에서 1월의 이벤트를 replace_data의 데이터로 원자적으로 교체하려면:

Python

(replace_data.write
  .mode("overwrite")
  .option("replaceWhere", "start_date >= '2017-01-01' AND end_date <= '2017-01-31'")
  .saveAsTable("events")
)

Scala

replace_data.write
  .mode("overwrite")
  .option("replaceWhere", "start_date >= '2017-01-01' AND end_date <= '2017-01-31'")
  .saveAsTable("events")

SQL

INSERT INTO TABLE events REPLACE WHERE start_date >= '2017-01-01' AND end_date <= '2017-01-31' SELECT * FROM replace_data

이 샘플 코드는 replace_data데이터를 작성하고, 모든 행이 조건자와 일치하는지 확인하고, 의미 체계를 사용하여 overwrite 원자성 대체를 수행합니다. 작업의 값이 조건자를 벗어나면 기본적으로 오류가 발생하여 이 작업이 실패합니다.

클래식 컴퓨팅에서 이 동작이 overwrite 조건자 범위 내의 값에 적용되고 insert 지정된 범위를 벗어난 레코드에 적용되도록 변경하려면 spark.databricks.delta.replaceWhere.constraintCheck.enabledfalse로 설정하여 제약 조건 검사를 제거합니다.

Python

spark.conf.set("spark.databricks.delta.replaceWhere.constraintCheck.enabled", False)

Scala

spark.conf.set("spark.databricks.delta.replaceWhere.constraintCheck.enabled", false)

SQL

SET spark.databricks.delta.replaceWhere.constraintCheck.enabled=false

Note

REPLACE WHEREboolean_expression 몇 가지 제한 사항을 허용합니다. SQL 언어 참조를 참조하세요 INSERT .

빈 원본 쿼리의 경우 테이블 행을 REPLACE WHERE 삭제할 수 있습니다.

레거시 작동 방식

레거시 replaceWhere 는 클래식 컴퓨팅에서만 사용할 수 있습니다. 클래식 컴퓨팅 개요를 참조하세요.

레거시 동작을 replaceWhere사용하는 경우 쿼리는 파티션 열에 대해서만 조건자와 일치하는 데이터를 덮어씁니다. 다음 명령은 date로 분할된 대상 테이블에서 1월을 원자적으로 df의 데이터로 대체합니다.

Python
(df.write
  .mode("overwrite")
  .option("replaceWhere", "birthDate >= '2017-01-01' AND birthDate <= '2017-01-31'")
  .saveAsTable("people10m")
)
Scala
df.write
  .mode("overwrite")
  .option("replaceWhere", "birthDate >= '2017-01-01' AND birthDate <= '2017-01-31'")
  .saveAsTable("people10m")

레거시 동작을 사용하려면 다음으로 spark.databricks.delta.replaceWhere.dataColumns.enabled설정합니다false.

Python
spark.conf.set("spark.databricks.delta.replaceWhere.dataColumns.enabled", False)
Scala
spark.conf.set("spark.databricks.delta.replaceWhere.dataColumns.enabled", false)
SQL
SET spark.databricks.delta.replaceWhere.dataColumns.enabled=false

동적 데이터 덮어쓰기

동적 데이터는 지정된 키 열 또는 부울 식과 일치하는 데이터를 선택적으로 대체하여 다른 모든 데이터를 변경하지 않고 덮어씁니다. 분할된 테이블, 분할되지 않은 테이블 및 액체 클러스터링이 있는 테이블이 모두 지원됩니다.

동적 파티션 덮어쓰기는 동적 데이터 덮어쓰기 동작의 하위 집합입니다. 동적 파티션 덮어쓰기는 쓰기가 새 데이터를 커밋하는 각 파티션의 기존 데이터를 모두 대체하고, 다른 모든 파티션은 변경하지 않습니다. 분할된 테이블만 지원됩니다.

REPLACE USING

Databricks Runtime 16.3 이상에서 지원되는 SQL입니다. Python 및 Scala는 Databricks Runtime 18.2 이상에서 지원됩니다. Databricks Runtime 16.3에서 17.1의 동작 차이는 레거시 동작을 참조하세요.

REPLACE USING 는 Databricks SQL 웨어하우스, 서버리스 컴퓨팅 및 클래식 컴퓨팅에서 작동하는 컴퓨팅 독립적 원자성 덮어쓰기 동작을 사용하도록 설정합니다. REPLACE USING 에서는 Spark 세션 구성을 설정할 필요가 없습니다.

REPLACE USING는 지정된 열이 동등 비교 시 서로 같으면 행을 대체합니다. 다른 모든 데이터는 변경되지 않은 상태로 유지됩니다.

REPLACE USING를 사용한 동적 데이터 덮어쓰기:

Python

(sourceDataDF.write
  .mode("overwrite")
  .option("replaceUsing", "event_id, start_date")
  .saveAsTable("events")
)

Scala

sourceDataDF.write
  .mode("overwrite")
  .option("replaceUsing", "event_id, start_date")
  .saveAsTable("events")

SQL

INSERT INTO TABLE events
  REPLACE USING (event_id, start_date)
  SELECT * FROM source_data

빈 원본 쿼리의 REPLACE USING 경우 테이블 행을 삭제하지 않습니다.

복잡하거나 NULL로부터 안전한 일치 조건의 경우 대신 사용합니다 REPLACE ON . REPLACE ON을(를) 참조하세요.

SQL 언어 참조를 참조하세요 INSERT .

레거시 동작 방식

Databricks Runtime 16.3~17.1 REPLACE USING 에서는 레거시 동작을 사용하고 동적 파티션 덮어쓰기만 허용하는 반면 Databricks Runtime 17.2 이상에서는 동적 데이터 덮어쓰기를 허용합니다.

REPLACE USING 레거시 동작과 관련하여 다음 제약 조건 및 동작을 유념하세요:

  • 테이블의 파티션 열 전체 집합을 USING 절에 지정해야 합니다.
  • 기록된 데이터가 예상 파티션에만 영향을 주는지 항상 확인합니다. 잘못된 파티션의 단일 행은 의도치 않게 전체 파티션을 덮어쓸 수 있습니다.

REPLACE ON

Databricks Runtime 17.1 이상에서 지원되는 SQL입니다. Python 및 Scala는 Databricks Runtime 18.2 이상에서 지원됩니다.

REPLACE ON는 사용자 정의 조건과 일치할 때 행을 대체하는 반면, REPLACE USING는 지정된 열 값이 동등 비교에서 같을 때 행을 대체합니다. REPLACE USING에서 지원하지 않는 일치 논리(예: NULL 값을 동일한 것으로 처리하는 경우)가 필요할 때는 REPLACE ON를 사용합니다.

선택적으로 targetAlias 옵션을 사용하여 대상 테이블의 별칭을 지정하고, .as() 또는 .alias() API를 사용하여 원본 데이터의 별칭을 지정할 수 있습니다.

SQL 구문은 다음을 참조하세요 INSERT.

Python

(sourceDataDF.alias("s")
  .write
  .mode("overwrite")
  .option("targetAlias", "t")
  .option("replaceOn", "s.event_id <=> t.event_id AND s.start_date <=> t.start_date")
  .saveAsTable("events")
)

Scala

sourceDataDF.as("s")
  .write
  .mode("overwrite")
  .option("targetAlias", "t")
  .option("replaceOn", "s.event_id <=> t.event_id AND s.start_date <=> t.start_date")
  .saveAsTable("events")

SQL

INSERT INTO TABLE events AS t
  REPLACE ON (s.event_id <=> t.event_id AND s.start_date <=> t.start_date)
  (SELECT * FROM source_data) AS s

빈 원본 쿼리의 REPLACE ON 경우 테이블 행을 삭제하지 않습니다.

동적 파티션 덮어쓰기 partitionOverwriteMode (레거시)

Databricks Runtime 11.3 LTS 이상에서는 SQL의 INSERT OVERWRITE 또는 DataFrame의 df.write.mode("overwrite")을 사용하여 덮어쓰기 모드로 분할된 테이블에 대한 동적 파티션 덮어쓰기를 지원합니다. 이 유형의 덮어쓰기는 Databricks SQL 웨어하우스 또는 서버리스 컴퓨팅이 아닌 클래식 컴퓨팅에만 사용할 수 있습니다.

경고

가능하면 파티션을 덮어쓰는 대신 INSERT REPLACE USING를 사용하고 INSERT OVERWRITE PARTITIONspark.sql.sources.partitionOverwriteMode=dynamic를 사용하십시오. 파티션 구성이 변경될 때 파티션 덮어쓰기가 오래된 데이터를 사용할 수 있습니다.

동적 파티션 덮어쓰기 모드를 사용하려면 Spark 세션 구성 spark.sql.sources.partitionOverwriteMode 을 .로 dynamic설정합니다. 또는 DataFrameWriter 옵션 partitionOverwriteModedynamic로 설정할 수 있습니다. 있는 경우 쿼리별 옵션은 세션 구성에 정의된 모드를 재정의합니다. spark.sql.sources.partitionOverwriteMode 의 기본값은 static입니다.

다음 예제에서는 partitionOverwriteMode를 사용합니다.

SQL

SET spark.sql.sources.partitionOverwriteMode=dynamic;
INSERT OVERWRITE TABLE default.people10m SELECT * FROM morePeople;

Python

(df.write
  .mode("overwrite")
  .option("partitionOverwriteMode", "dynamic")
  .saveAsTable("default.people10m")
)

Scala

df.write
  .mode("overwrite")
  .option("partitionOverwriteMode", "dynamic")
  .saveAsTable("default.people10m")

다음 제약 조건 및 동작을 partitionOverwriteMode에 유의하세요.

  • overwriteSchematrue로 설정할 수 없습니다.
  • 동일한 partitionOverwriteMode 작업에서 replaceWhereDataFrameWriter를 둘 다 지정할 수 없습니다.
  • 옵션을 사용하여 replaceWhere 조건을 지정 DataFrameWriter 하는 경우 Delta Lake는 해당 조건을 적용하여 덮어쓸 데이터를 제어합니다. 이 옵션은 세션 수준 구성보다 partitionOverwriteMode 우선합니다.
  • 기록된 데이터가 예상 파티션에만 영향을 주는지 항상 확인합니다. 잘못된 파티션의 단일 행은 의도치 않게 전체 파티션을 덮어쓸 수 있습니다.