データのセットアップ
はじめに
Netuno では、アプリケーション開発はまずデータベースの構築から始まり、フォームとフィールドの作成を通じて行われます。
チームで作業する場合や、アプリケーションの開発を別の環境へ移す必要がある場合は、コードと合わせてデータベースのバックアップを作成する必要があります。
そのため、移行先ではデータベースを再設定する必要があり、そうすることでアプリケーションは開発元と同じように実行できるようになります。
このプロセスの問題は、データベースに変更があるたびに新しいバックアップを作成することを常に覚えておかなければならない手間です。また、開発に関わる人数が増えたり、アプリケーションを公開する環境が増えたりするほど、このプロセスは複雑になります。
そこで Netuno はこの問題を解決するために、アプリケーションの セットアップ システムを提供しています。これによりデータベース構造(スキーマ)を自動生成し、さらに追加の スクリプト を通じて初期データの読み込みを手動でプログラムできるようにします。
また、データベースサーバーの種類を変更しても、セットアップ が正常に実行され、アプリケーションが問題なく動作することを保証します。つまり、アプリケーションを H2DataBase で開発し、自動生成されたスキーマによって、アプリケーションのデータベース接続を PostgreSQL や MariaDB に変更できます。新しいデータベース上でアプリケーションを初回実行すると、データベースサーバーの種類の変更に関係なく、すべてが再構築されます。
これにより、すでに行われた開発に影響を与えることなく、データベースを完全に変更できます。
セットアップのプログラムファイルは、アプリケーションの次のフォルダー内にあります:
server/setup
セットアップの設定
アプリケーションの環境設定は次の場所にあります:
/apps/MY_APP/config/_development.json/apps/MY_APP/config/_production.json
セットアップの動作は、次の設定で制御できます:
...
"setup": {
"enabled": true,
"schema": {
"auto_create": true,
"execution": true
},
"scripts": {
"execution": true
}
},
...
enabled: boolean > デフォルト true
セットアップが有効かどうかを定義し、アプリケーションの初回実行時にデータセットアップ操作の実行を有効または無効にします。
schema.auto_create: boolean > デフォルト true
フォームやフィールドが作成または変更されるたびに、Netuno がデータベーススキーマファイルを生成するかどうかを指定します。
schema.execution: boolean > デフォルト true
アプリケーションの初回実行時に行われるセットアップ操作で、スキーマを実行するかどうかを制御します。
scripts.execution: boolean > デフォルト true
アプリケーションの初回実行時に行われるセットアップ操作で、追加スクリプトの実行を有効または無効にします。
スキーマ
Netuno の Web インターフェースでフォームやフィールドを作成または変更すると、セットアップフォルダー内に次の形式でスキーマファイルが生成されます:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
server/setup/_schema-FORM_NAME.js
server/setup/_schema-FORM_NAME.ts
server/setup/_schema-FORM_NAME.py
server/setup/_schema-FORM_NAME.rb
server/setup/_schema-FORM_NAME.kts
server/setup/_schema-FORM_NAME.groovy
アプリケーション内の各フォームに対して、_schema-*** というファイルが作成されます。
これらのファイルは Netuno によって自動生成されるため、手動で変更しないでください。
これらのファイルの内容を変更した場合、次回のスキーマ生成時に自動的に置き換えられ、ファイルに直接加えた変更は失われます。
データベーススキーマの自動生成を実行するには、設定 schema.auto_create が有効であること、および server フォルダー内に setup フォルダーが存在することを確認してください。
スクリプト
カスタムプログラムされたスクリプトは、setup フォルダー内にある、_ で始まらないファイルです。
これらのスクリプトの主な目的は、アプリケーションが正しく動作するために必要な最小限の情報がデータベースに含まれるように、データを読み込むことです。
これにより、アプリケーションを別の環境で再設定すると、初期データが自動的に読み込まれ、すぐに利用を開始できる状態になります。
これらのデータ読み込み操作を行うには、リソース _db の関数を使用します。
スクリプト は スキーマ の実行後、_ で始まらないファイル名の英数字順で実行されます。
実行順序を定義するには、ファイル名を数値シーケンスで始めるのが理想的です。そのため、カスタムスクリプトは
_で始まらないファイル名の順序で実行されます。
カスタムデータの挿入
また、データを 挿入 できるかどうかを確認するためにデータベースへ問い合わせる手間を省くため、Netuno は insertIfNotExists 関数を提供しています。
この関数は、定義されたとおりのデータがデータベースに存在するかどうかを確認し、存在しない場合は作成します。
使用例として、フォーム 地域種別 のフィールド コード と 名前 を読み込みます。テーブル名は territory_type、列は code と name です。そのためには、次の内容でファイルを作成するだけです:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_db.insertIfNotExists("territory_type", _val.map()
.set("code", "1001")
.set("name", "大陸")
);
_db.insertIfNotExists("territory_type", _val.map()
.set("code", "1002")
.set("name", "群島")
);
_db.insertIfNotExists("territory_type", _val.map()
.set("code", "2003")
.set("name", "海洋")
);
_db.insertIfNotExists("territory_type", _val.map()
.set("code", "3004")
.set("name", "航空")
);
_db.insertIfNotExists("territory_type", _val.map()
.set("code", "1001")
.set("name", "大陸")
);
_db.insertIfNotExists("territory_type", _val.map()
.set("code", "1002")
.set("name", "群島")
);
_db.insertIfNotExists("territory_type", _val.map()
.set("code", "2003")
.set("name", "海洋")
);
_db.insertIfNotExists("territory_type", _val.map()
.set("code", "3004")
.set("name", "航空")
);
_db.insertIfNotExists("territory_type", _val.map()
.set("code", "1001")
.set("name", "大陸")
)
_db.insertIfNotExists("territory_type", _val.map()
.set("code", "1002")
.set("name", "群島")
)
_db.insertIfNotExists("territory_type", _val.map()
.set("code", "2003")
.set("name", "海洋")
)
_db.insertIfNotExists("territory_type", _val.map()
.set("code", "3004")
.set("name", "航空")
)
_db.insertIfNotExists("territory_type", _val.map()
.set("code", "1001")
.set("name", "大陸")
)
_db.insertIfNotExists("territory_type", _val.map()
.set("code", "1002")
.set("name", "群島")
)
_db.insertIfNotExists("territory_type", _val.map()
.set("code", "2003")
.set("name", "海洋")
)
_db.insertIfNotExists("territory_type", _val.map()
.set("code", "3004")
.set("name", "航空")
)
_db.insertIfNotExists("territory_type", _val.map()
.set("code", "1001")
.set("name", "大陸")
)
_db.insertIfNotExists("territory_type", _val.map()
.set("code", "1002")
.set("name", "群島")
)
_db.insertIfNotExists("territory_type", _val.map()
.set("code", "2003")
.set("name", "海洋")
)
_db.insertIfNotExists("territory_type", _val.map()
.set("code", "3004")
.set("name", "航空")
)
_db.insertIfNotExists("territory_type", _val.map()
.set("code", "1001")
.set("name", "大陸")
)
_db.insertIfNotExists("territory_type", _val.map()
.set("code", "1002")
.set("name", "群島")
)
_db.insertIfNotExists("territory_type", _val.map()
.set("code", "2003")
.set("name", "海洋")
)
_db.insertIfNotExists("territory_type", _val.map()
.set("code", "3004")
.set("name", "航空")
)
処理サイクル
すでに説明したとおり、セットアップ はアプリケーションの初回実行時にのみ実行されます。
実行順序は次のとおりです:
_start- 任意のカスタムプログラムを含められる初期化ファイルを実行します:- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
MY_APP/server/setup/_start.js
MY_APP/server/setup/_start.ts
MY_APP/server/setup/_start.py
MY_APP/server/setup/_start.rb
MY_APP/server/setup/_start.kts
MY_APP/server/setup/_start.groovy
_cleanup- フォーム、レポート、およびそれぞれのフィールドをプログラムで削除します:- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
MY_APP/server/setup/_cleanup.js
MY_APP/server/setup/_cleanup.ts
MY_APP/server/setup/_cleanup.py
MY_APP/server/setup/_cleanup.rb
MY_APP/server/setup/_cleanup.kts
MY_APP/server/setup/_cleanup.groovy
_schema-*-_schema-*プレフィックスを持つすべてのスクリプトを実行します。フォーム、レポート、およびそれぞれのフィールドを作成するコマンドが含まれます:- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
MY_APP/server/setup/_schema-auto_generated_structure.jsMY_APP/server/setup/_schema-category.jsMY_APP/server/setup/_schema-product.jsMY_APP/server/setup/_schema-customer.js
MY_APP/server/setup/_schema-auto_generated_structure.tsMY_APP/server/setup/_schema-category.tsMY_APP/server/setup/_schema-product.tsMY_APP/server/setup/_schema-customer.ts
MY_APP/server/setup/_schema-auto_generated_structure.pyMY_APP/server/setup/_schema-category.pyMY_APP/server/setup/_schema-product.pyMY_APP/server/setup/_schema-customer.py
MY_APP/server/setup/_schema-auto_generated_structure.rbMY_APP/server/setup/_schema-category.rbMY_APP/server/setup/_schema-product.rbMY_APP/server/setup/_schema-customer.rb
MY_APP/server/setup/_schema-auto_generated_structure.ktsMY_APP/server/setup/_schema-category.ktsMY_APP/server/setup/_schema-product.ktsMY_APP/server/setup/_schema-customer.kts
MY_APP/server/setup/_schema-auto_generated_structure.groovyMY_APP/server/setup/_schema-category.groovyMY_APP/server/setup/_schema-product.groovyMY_APP/server/setup/_schema-customer.groovy
001-other_scripts- カスタムプログラムされた スクリプト ファイルを実行します。_で始まらないすべてのファイルで、必要な初期データの 挿入 やその他のカスタム開発が含まれる可能性があります。例:- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
MY_APP/server/setup/001-insert_custom_data.jsMY_APP/server/setup/002-category.jsMY_APP/server/setup/003-product.jsMY_APP/server/setup/004-customer.js
MY_APP/server/setup/001-insert_custom_data.tsMY_APP/server/setup/002-category.tsMY_APP/server/setup/003-product.tsMY_APP/server/setup/004-customer.ts
MY_APP/server/setup/001-insert_custom_data.pyMY_APP/server/setup/002-category.pyMY_APP/server/setup/003-product.pyMY_APP/server/setup/004-customer.py
MY_APP/server/setup/001-insert_custom_data.rbMY_APP/server/setup/002-category.rbMY_APP/server/setup/003-product.rbMY_APP/server/setup/004-customer.rb
MY_APP/server/setup/001-insert_custom_data.ktsMY_APP/server/setup/002-category.ktsMY_APP/server/setup/003-product.ktsMY_APP/server/setup/004-customer.kts
MY_APP/server/setup/001-insert_custom_data.groovyMY_APP/server/setup/002-category.groovyMY_APP/server/setup/003-product.groovyMY_APP/server/setup/004-customer.groovy
- _end - 任意のカスタムプログラムを含められる終了ファイルを実行します:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
MY_APP/server/setup/_end.js
MY_APP/server/setup/_end.ts
MY_APP/server/setup/_end.py
MY_APP/server/setup/_end.rb
MY_APP/server/setup/_end.kts
MY_APP/server/setup/_end.groovy
つまり、セットアップの前に実行するのが適切な操作や、セットアップ完了時に実行するのが適切な操作を行うために、start および end スクリプトでカスタムコードを作成できます。
この処理サイクルは、アプリケーションが初回実行されるたびに実行されるため、データを作成する前にその存在を確認する必要があることを強調しておきます。
環境に応じて、MY_APP/config/_development.json または MY_APP/config/_production.json でこのプロセスを実行できるように、次の環境 設定 が有効になっていることを確認してください:
-
任意のセットアップ操作の実行を完全に有効または無効にします:
setup.enabled = true|false -
_schema-*の実行を有効または無効にします:setup.schema.execution = true|false -
スクリプト の実行を有効または無効にします:
setup.scripts.execution = true|false
クリーンアップ
フォームやフィールドの削除をプログラムするには、_cleanup.js スクリプトを使用します。これにより、プロジェクトのファイルを同期するすべての環境で、セットアップ実行時に構造が存在する場合は削除されることが保証されます。
クリーンアップスクリプトの例:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
// フォーム zone を削除します:
_form.dropIfExists("zone");
// フォーム area のフィールド subarea_id を削除します:
_form.dropFieldIfExists("area", "subarea_id");
// フォーム zone を削除します:
_form.dropIfExists("zone");
// フォーム area のフィールド subarea_id を削除します:
_form.dropFieldIfExists("area", "subarea_id");
# フォーム zone を削除します:
_form.dropIfExists("zone")
# フォーム area のフィールド subarea_id を削除します:
_form.dropFieldIfExists("area", "subarea_id")
# フォーム zone を削除します:
_form.dropIfExists("zone")
# フォーム area のフィールド subarea_id を削除します:
_form.dropFieldIfExists("area", "subarea_id")
// フォーム zone を削除します:
_form.dropIfExists("zone")
// フォーム area のフィールド subarea_id を削除します:
_form.dropFieldIfExists("area", "subarea_id")
// フォーム zone を削除します:
_form.dropIfExists("zone")
// フォーム area のフィールド subarea_id を削除します:
_form.dropFieldIfExists("area", "subarea_id")
DBML
Netuno がデータセットアップを実行するたびに、次のファイルが生成されます:
server/setup/_db-schema.dbml
これは、人工知能とともに使用できるすべてのデータ構造を含むファイルです。
DBML の内容に基づいて、人工知能はデータ構造を理解し、正確な SQL クエリを生成できます。
このファイルをプロンプトの添付として使用し、複雑な SQL クエリの生成を依頼してみてください。良い結果が得られます。
まとめ
Netuno におけるアプリケーションの セットアップ プロセスの主な機能は次のとおりです:
- _schema-: フォームおよびレポートとそれぞれのフィールドの構造全体を自動生成し、特にアプリケーションが新しい空のデータベースで実行される場合に、アプリケーションのデータベース構造全体の整合性を保証します。
- スクリプト: アプリケーションが初回実行されるたびに、必須データがあらかじめ読み込まれていることを保証するためにデータベース操作を実行します。
このように、Netuno はデータベースの種類を変更してもアプリケーションが新しい環境で動作できるようにし、データベースの バックアップ や リストア を行うことなく、アプリケーションの正常な動作を保証します。
さらに、自動および手動で生成されたすべての設定コードを、たとえば GIT でバージョン管理できるようにします。