DBマイグレーション導入

DBマイグレーションの紹介

繰り返し実行可能なマイグレーション

@View、extra-ddl.xml、繰り返し実行可能なマイグレーションの使用

出力ファイル

DBマイグレーションには2つの出力ファイルがあります

  • マイグレーションモデルXML - モデルの論理的な差分をapplyまたはpendingDrops変更セットとして含んでいます。
  • 適用SQL - これは、apply変更のDDLスクリプトです。

DbMigrationが実行されると、以前のマイグレーションXMLが読み込まれ、それらが結合されて以前のモデルが定義されます。その後、既存のエンティティBeanと比較されます。

保留中の削除

非破壊的な変更のみがapplyに含まれ、drop tabledrop columnなどの変更はpendingDrops変更セットに配置されます。

保留中の削除変更は、マイグレーションに明示的に選択する必要があります。

クラスタ環境で実行されているアプリケーションでは、保留中の削除は通常、通常のapply変更よりも少なくとも1つのマイグレーション遅れる必要があります。この遅延は数分、数日かかる場合があり、一部の削除は実行されない可能性があります。

マイグレーションXML

DbMigrationが実行されると、モデルに対するdiffが決定され、マイグレーションモデルXMLドキュメントとして出力されます。このdiffには、apply変更またはpendingDrops変更が含まれる可能性があります。

マイグレーションapply変更セットから、実際に適用されるDDLが生成されます。

論理的な変更

マイグレーションXMLの変更はデータベースに依存せず、単一のマイグレーションXMLドキュメントを使用して複数のデータベースのマイグレーションDDLを生成できます。たとえば、単一のマイグレーションXMLからPostgreSQL、Oracle、SQL ServerのマイグレーションDDLスクリプトを生成できます。マイグレーションXMLには、JSONタイプ(DBへのJSONドキュメントの格納)などの論理的なタイプが表示され、PostgreSQLではJSONBに、OracleではCLOBに変換される可能性があります。

変更は、「論理的」であるという意味でも、@Historyと@Draftableを持つエンティティへの変更は通常、複数の変更に変換されるという意味です。たとえば、@Historyエンティティにプロパティを追加すると、基本テーブルに列を追加し、履歴テーブルに列を追加し、必要に応じてトリガーを変更する可能性があります。

マイグレーションXMLの例

以下は、apply変更を使用して生成されたマイグレーションXMLの例です。customerテーブルに2つの新しい列が追加されています。

customerテーブルに@Historyサポートがある場合、履歴テーブルにも列が追加され、関連するDBトリガーが更新される可能性があります。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration">
  <changeSet type="apply">
    <addColumn tableName="customer">
      <column name="registered" type="date"/>
      <column name="comments" type="varchar(1000)"/>
    </addColumn>
  </changeSet>
</migration>

pendingDropsを含むマイグレーションの例

以下は、pendingDrops変更を使用して生成されたマイグレーションXMLの例です。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration">
  <changeSet type="pendingDrops">
    <dropColumn columnName="shortTitle" tableName="document" withHistory="true"/>
  </changeSet>
</migration>

保留中の削除変更は、明示的に選択しない限り、apply DDLスクリプトに組み込まれません。保留中の削除が適用されると、「保留中の削除」リストから削除されます。

DDLの適用

apply ddlスクリプトには、データベースに適用する変更が含まれています。これは、FlywayDBなどで実行するDDLスクリプトです。

保留中の削除の適用

INFO  c.a.ebean.dbmigration.DbMigration - Pending un-applied drops in versions [1.2]

DBマイグレーションは、まだ適用されていない保留中の削除を含むマイグレーションをINFOレベルのメッセージでログに記録します。ある時点で、次のマイグレーションとして保留中の削除の1つを適用することが決定されます。

// generate a migration as the drops from migration version "1.2"
System.setProperty("ddl.migration.pendingDropsFor", "1.2");

DbMigration dbMigration = DbMigration.create();
dbMigration.setPlatform(Platform.POSTGRES);
dbMigration.generateMigration();
// generate a migration as the drops from migration version "1.2"
System.setProperty("ddl.migration.pendingDropsFor", "1.2")

DbMigration.create().apply {
  setPlatform(Platform.POSTGRES)
}.generateMigration()

次に、dropsForが適用する保留中の削除が含まれていたマイグレーションのバージョンに設定されたマイグレーションが生成されます。さらに、マイグレーションapply ddlには、実行されるさまざまな削除ステートメントが含まれています。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration">
  <changeSet type="apply" dropsFor="1.2">
    <dropColumn columnName="shortTitle" tableName="document" withHistory="true"/>
  </changeSet>
</migration>

バージョン形式

サポートされている「バージョン」番号付け形式は、FlywayDBのバージョン番号付けと同じで、区切り文字として「.」または「_」(ピリオドまたはアンダースコア)を使用できます。

そのため、1.11_1はどちらもバージョン1.1として解釈されます。

バージョン番号付けは、マイグレーションが実行される順序を制御し、セマンティックバージョン管理に従うことに注意してください。たとえば、1.1.11.2の前に実行されます。この方法で、「パッチ」マイグレーションを追加できます。

ワークフロー

Ebeanのマイグレーションランナーを使用してマイグレーションを実行する場合、マイグレーションを実行するための要件として、前のマイグレーションが実行されている必要があります。これは、厳密なバージョン番号順序を必要とする(または任意の順序を許可するために無効にできる)FlywayDBとはやや異なります。

「git flow」に似たワークフローを使用している場合、Ebeanのマイグレーションランナーでは、非厳密な順序でマージリクエストを処理できます。これが機能するための前提条件は、2つ以上のマージリクエスト(レビュー中で、共通のDEVブランチにまだマージされていない)が、競合するDBマイグレーション変更を持たないということです(もしあれば、Ebeanはマイグレーションの実行を許可しますが、マイグレーション自体がエラーになります)。

マイグレーションバージョンと名前

マイグレーションでは、開発者はバージョン名前を提供する必要があり、これらは環境変数、システムプロパティ、ebean.properties、またはプログラムによって設定できます。

System.setProperty("ddl.migration.version", "1.1");
System.setProperty("ddl.migration.name", "support end dating");
System.setProperty("ddl.migration.version", "1.1")
System.setProperty("ddl.migration.name", "support end dating")

オフラインでの生成

アプリケーションを開始せずに、プログラムでマイグレーションを生成できます。src/test/javaに、mainメソッドを含む次のコードを追加します。

このmainメソッドを実行すると、次のマイグレーションが生成され、Ebeanがオフラインモードで起動します。このオフラインモードでは、アプリケーションを開始したり、マイグレーションを生成するためにデータベースを必要とする必要はありません。

package main;

import io.ebean.annotation.Platform;
import io.ebean.dbmigration.DbMigration;
import java.io.IOException;

public class GenerateDbMigration {

  /**
   * Generate the next "DB schema DIFF" migration.
   */
  public static void main(String[] args) throws IOException {

    DbMigration dbMigration = DbMigration.create();
    dbMigration.setPlatform(Platform.POSTGRES);

    dbMigration.generateMigration();
  }
}
import io.ebean.annotation.Platform
import io.ebean.dbmigration.DbMigration

fun main() {
  DbMigration.create().apply {
    setPlatform(Platform.POSTGRES)
  }.generateMigration()
}

マイグレーションの実行

FlywayDbLiquibase、またはEbean独自の組み込みマイグレーションランナーを使用してマイグレーションを実行できます。

Ebeanのマイグレーションランナー

## run migrations when Ebean starts
ebean.migration.run=true

## optionally specify different DB credentials
## to run the migration (own the tables)
datasource.db.adminusername=myDbTableOwner
datasource.db.adminpassword=secret

ebean.migration.run=trueの場合、EbeanServerが起動すると、マイグレーションが確認され、実行する必要があるマイグレーションが実行されます。マイグレーションランナーは、デフォルトでdb_migrationというテーブルを作成し、実行されたマイグレーションに関するメタデータが格納され、マイグレーションが正常に実行されるとこのテーブルに挿入されます。

繰り返し実行可能なマイグレーション

繰り返し実行可能なマイグレーションは、R__で始まり、バージョン番号を持たない特別なマイグレーションです。繰り返し実行可能なマイグレーションは、まだ実行されていない場合、またはコンテンツが変更されている場合(MD5チェックサムが変更されている場合)に実行されます。

繰り返し実行可能なマイグレーションには任意のDDLを含めることができますが、ORMでは、データベースビューの定義に使用し、たとえば、エンティティBeanをテーブルではなくデータベースビューにマッピングするために@Viewを使用します。

extra-ddl.xmlと@Viewを使用した繰り返し実行可能なマイグレーションを示す2番目のビデオを参照してください。

繰り返し実行可能なマイグレーション

@View、extra-ddl.xml、繰り返し実行可能なマイグレーションの使用

FlywayDBに関する注記

FlywayDBで使用するには、現在、「バージョンマイグレーション」と「繰り返し実行可能なマイグレーション」の両方をサポートするために、「バージョンマイグレーション」にVをプレフィックスする必要があります。これを行うには

## must use V prefix on "version migrations" when using FlywayDB
## with both "version" and "repeatable" migrations
ebean.migration.applyPrefix=V