web-dev-qa-db-ja.com

生産の取り扱いSeedデータ

機能が正しく機能するためには、データベースにシードデータ(基本的にはいくつかのデフォルト値)が存在する必要がある新しい機能が必要です。現在、これは2つの異なるシナリオにあり、シードデータの生成/挿入の最良の方法は、使用するデータストアによって異なるようです。ここでは、テスト目的でデータをシードすることについて話しているのではありません。

たとえば、一部の機能では、SQL Serverにテーブルが存在する必要があります。バージョン間の手動移行(基本的にはスキーマの相違)を使用しているため、このためのシードデータの挿入は、スキーマを更新する同じSQLスクリプトで実行するのが理にかなっています。一部のORMがこれを処理するように見える方法は、データを作成する初期化コードにSeed()メソッド(または同等のメソッド)を含めることです。

別の機能は、データストアとしてAzure Table Storage(ATS)を使用することです。スキーマレスであるため、ここにテーブルを作成するスクリプトはありませんが、アプリケーションは初回実行時にテーブルの存在を確認し、テーブルが存在しない場合は作成します。つまり、通常、展開を進める前にテーブルを作成しません。 ATSにデータをシードするには、環境を事前に設定するか(コードを記述してどこかに実行する必要がある)、テーブルの存在を確認するコンポーネントに、作成時にデータを挿入させることができます。

コード内のクラスにシードデータを含めることには長期的な不利な点がありますか?それがそれを配置するのに最適な場所である場合、データをまとめておく方が理にかなっています(たとえば、Seedアプリの起動時に実行されるデータを含むクラス)または Repository は、クエリを発行する前に基本データが存在することを確認する責任がありますか?

4

実際には2つのものが必要です。

  • 何らかのアクションが必要であることを決定するメカニズム(つまり、シードデータを追加する必要がある)
  • シードデータと、シードデータをターゲットストレージに転送するコード(sql-scriptまたはcsv-data + csv-interpreter)

私はこのような問題を解決します:

  • ターゲットストレージにバージョン番号を追加します
  • バージョン変更スクリプトの命名規則を定義します
    • 例version-update-1-2.sqlはバージョン1からバージョン2に更新されます
    • Version-update-1-2.exeの例(プロセスがスクリプト可能でない場合(インタープリターを介して実行)
  • Version-update- *の最後のステップでは、新しいバージョン番号を設定します。
  • プログラムの起動時に、コードは利用可能な更新があるかどうかを確認して実行します。
  • 更新スクリプトは、正常に実行されると安全に削除できます。

製品に機能を追加する場合

  • データのバージョン番号を増やす
  • 命名規則に一致する更新スクリプトを提供します。

コードのクラスにシードデータを含めることには長期的な欠点がありますか?それがそれを置くのに最適な場所である場合

  • proコードは自己完結型です。更新は、数年後にまだ価値がある可能性が高いです。
  • contra更新ステップを削除することはより困難です。時間が経つにつれて、コードはどんどん乱雑になります。
  • システムが変更されると、古い更新手順が正常に機能しない可能性があります。
2
k3b

コードに追加する場合、アプリケーションの起動時にDBをシードする必要があることを検出して実行する場合は、コードに追加しないでください。これにはいくつかの理由があります(Alphaが提供するものと類似または同じものもあります)。

  • これを理解しているように、本番環境で1回だけ実行する必要があります。コードにこのプロシージャを含めることは、最初の実行後は意味がありません。
  • 時間が経つにつれて、誰もこのコードの目的や、なぜそこにあったのか覚えていないでしょう。新しい人(または一度にそれを知っていた人でさえ)はそれを見て「WTF?これだ」と考えるでしょう。最良のシナリオは、誰かがソース管理からそれを削除することです。
  • なんらかの理由で何か問題が発生し、アプリが新規インストールを検出する状態になった場合、これは再度実行され、問題なく進行します。これは望ましくありません。 Fail fast 代わりに。アプリケーションがその状態でしばらく実行されている場合、クリーンアップするのは本当の混乱かもしれません。

これは、コードの一部ではなく、コードのデプロイメントの一部である必要があります。これにより、シードの作成が意図的に行われます。

1
JimmyJames

コードのクラスにシードデータを含めることには長期的な欠点がありますか?それがそれを置くのに最適な場所である場合

逆に、これはこの種の初期化を行うのに最適な場所だと私は主張します。コードはこのデータ、その形状、内容に直接依存しているため、この初期化がコードに直接結び付けられていることは、実際に起こり得る最高のことです。

ただし、通常は誰もそれを行いません。通常、いくつかの理由により、スクリプトまたはデプロイメントステップを作成します。

  1. 初期化コードは常に実行する必要はありません。これを特定の1回限りのシナリオでコーディングしても、通常は実りがありません。これをコードベースに組み込むには、保守とテストも必要であることを忘れないでください。
  2. 実際の環境で初期化が完了すると、データへの変更を管理する方法がない限り、特定のコンテンツセットにロックされます。これは、単純な初期化コードだけでは機能しません。

これがコードベースで処理される例として、Entity FrameworkやRailsの移行があります。初期化、更新、データのシードと変換を行います。

実際のストレージはそれほど重要ではありません。 Azure Tablesはスキーマレスである可能性がありますが、コードでは、そのデータを操作するために特定のスキーマが存在する必要があります。

これを言っても、私の推奨事項は次のとおりです。

  1. 可能であれば、このシードロジックをコードに含めます。そのデータとその変更を維持する準備をします。古い環境データを準備します。前後に移行する準備をします。
  2. 既知のフレームワークに委任できる場合は、委任してください。それはあなたのコードから多くの膨らみをとります。
  3. このロジックをリポジトリに含めないでください。データソースの初期化ではなく、データアクセスを処理する必要があります。
0
Alpha