Zum Inhalt springen
Anjunar/ DOCS

Pflichtspalten und Backfills

Eine Spalte wird erst Pflicht, wenn keine Zeile mehr NULL enthält. Die Werte für bestehende Zeilen kommen aus einem Backfill, den du registrierst.

Pflicht

Erst nullable, NOT NULL nach dem Zählen

Eine neue Pflichtspalte in einer bestehenden Tabelle wird nullable angelegt. Pflicht wird sie mit SET NOT NULL, nachdem der Executor unter der Sperre gezählt hat, dass keine Zeile NULL enthält. Bleibt eine NULL, schlägt die Migration fehl und wird zurückgerollt.

Eine neue Pflichtspalte funktioniert also in einer leeren Tabelle, und eine Spalte wird Pflicht, sobald ihre Zeilen gefüllt sind. Optional wird sie wieder mit DROP NOT NULL; Primärschlüssel- und Identity-Spalten bleiben Pflicht.

Backfill

Werte, die die Anwendung festlegt

Das Framework erfindet nie einen Wert. Ein Backfill nennt seine Zielspalte per ID, läuft, wenn die Spalte Pflicht wird, und füllt nur die NULLs.

scala
import com.anjunar.hibernateddl.core.* val backfills = Vector( Backfill.fillNulls( id = "user-display-name-v1", target = SchemaId("7f3a9c21/4f5a6b7c"), when = BackfillTrigger.BecomesRequired, value = BackfillValue.coalesce( BackfillValue.concat( BackfillValue.column(SchemaId("7f3a9c21/1a2b3c4d")), BackfillValue.literal(" "), BackfillValue.column(SchemaId("7f3a9c21/2b3c4d5e")) ), BackfillValue.literal("Unknown") ) ) ) HibernateSchemaMigration.migrate(metadata, dataSource, backfills = backfills)
Ausgabe
UPDATE "public"."users" SET "display_name" = COALESCE(("first_name" || CAST(? AS varchar(255)) || "last_name"), CAST(? AS varchar(255))) WHERE "display_name" IS NULL
Werte

Was ein Backfill verwenden darf

Konstanten sind immer JDBC-Parameter. Eine Konstante muss ohne Umwandlung oder Rundung in die Spalte passen, eine Quellspalte den Typ des Ziels haben oder Text für Text sein.

BackfillValue.literal(value)
Eine Konstante: Text, Zahlen, Boolean, UUID, Datums- und Zeittypen.
BackfillValue.column(id)
Eine andere Spalte derselben Zeile, per stabiler ID.
BackfillValue.coalesce(values*)
Der erste Wert, der nicht NULL ist.
BackfillValue.concat(values*)
Verketteter Text; NULL, wenn ein Teil NULL ist.
Lebenszyklus

Einmal registriert, einmal ausgeführt

Ein Backfill wird mit der Prüfsumme seiner Definition in __hibernate_ddl.backfill_history eingetragen. Dieselbe ID mit anderer Definition blockiert den Start.

Regeln
Der Integrator findet Backfills über META-INF/services/com.anjunar.hibernateddl.integration.BackfillProvider.
Der explizite Aufruf ergänzt die Backfills der Provider um eigene; eine doppelte ID wird abgelehnt.
Behalte die Regeln jedes Releases, das ein Server noch überspringen darf.
Eine Regel, deren Spalte nicht Pflicht wird, bleibt offen in MigrationResult.pendingBackfills.
Backfills laufen in der Migration

Sie laufen in ihrer Transaktion, während ihre Tabellen exklusiv gesperrt sind. Große Tabellen und Deployments ohne Ausfallzeit brauchen eine eigene, schrittweise Datenmigration.