データベースマイグレーションは、データベースに加えられる変更です。これらの変更には、テーブルのスキーマの変更、レコードのデータの更新、データのシーディング、または一連のレコードの削除が含まれる場合があります。
データベースマイグレーションは通常、アプリケーションが開始する前に実行され、同じデータベースに対して成功裏に二度実行されることはありません。データベースマイグレーションツールは、データベースで実行されたマイグレーションの履歴を保存し、将来の目的のために追跡できるようにします。
この記事では、最小限のNode.js APIアプリケーションでデータベースマイグレーションを設定して実行する方法を学びます。私たちは、ts-migrate-mongooseとnpmスクリプトを使用して、マイグレーションを作成し、MongoDBデータベースにデータをシードします。ts-migrate-mongooseは、TypeScriptコードとCommonJSコードの両方からマイグレーションスクリプトを実行することをサポートしています。
ts-migrate-mongooseは、mongooseをオブジェクトデータマッパーとして使用するNode.jsプロジェクトのためのマイグレーションフレームワークです。マイグレーションスクリプトを書くためのテンプレートを提供し、スクリプトをプログラム的におよびCLIから実行するための設定も提供します。
目次
プロジェクトのセットアップ方法
データベース移行のためにts-migrate-mongooseを使用するには、以下が必要です:
-
mongooseが依存関係としてインストールされたNode.jsプロジェクト。
-
プロジェクトに接続されたMongoDBデータベース。
-
MongoDB Compass(オプション – データベースの変更を表示するために使用)。
簡単にするために作成されたts-migrate-mongoose-starter-repoからクローンできるスターターリポジトリが用意されています。リポジトリをクローンし、環境変数を入力してnpm start
コマンドを実行してアプリケーションを起動します。
http://localhost:8000をブラウザやPostmanなどのAPIクライアントで開くと、サーバーが正常に起動していることを示す「Hello there!」テキストが返されます。
プロジェクトのts-migrate-mongooseの構成方法
プロジェクトのts-migrate-mongooseを構成するには、次のコマンドでts-migrate-mongooseをインストールします:
npm install ts-migrate-mongoose
ts-migrate-mongooseでは、JSONファイル、TypeScriptファイル、.env
ファイル、またはCLIを使用して構成できます。構成内容にはデータベースのパスワードが含まれる可能性があるため、一般公開することは適切ではありません。通常、.env
ファイルは.gitignore
ファイルで非表示にされるため、より安全に使用できます。このプロジェクトでは、ts-migrate-mongooseの構成に.env
ファイルを使用します。
ファイルには、次のキーとその値を含める必要があります:
-
MIGRATE_MONGO_URI
– MongoデータベースのURI。これはデータベースのURLと同じです。 -
MIGRATE_MONGO_COLLECTION
– マイグレーションが保存されるコレクション(またはテーブル)の名前です。デフォルト値はこのプロジェクトで使用されているmigrationsです。ts-migrate-mongooseはマイグレーションをMongoDBに保存します。 -
MIGRATE_MIGRATIONS_PATH
– マイグレーションスクリプトを格納および読み取るためのフォルダへのパスです。デフォルト値は./migrations
で、このプロジェクトで使用されています。
ts-migrate-mongooseを使用してユーザーデータをシードする方法
プロジェクトを作成し、Mongoデータベースに正常に接続できました。この段階で、データベースにユーザーデータをシードしたいと思います。以下の手順が必要です:
-
ユーザーコレクション(またはテーブル)を作成する
-
データをシードするためのマイグレーションスクリプトを作成するためにts-migrate-mongooseを使用する
-
アプリケーションの開始前にユーザーデータをデータベースにシードするためにts-migrate-mongooseを実行する
1. Mongooseを使用してusersコレクションを作成します
Mongooseスキーマを使用してユーザーコレクション(またはテーブル)を作成できます。ユーザードキュメント(またはレコード)には次のフィールド(または列)が含まれます:email
、favouriteEmoji
、およびyearOfBirth
。
ユーザーコレクションのためのMongooseスキーマを作成するには、プロジェクトのルートにuser.model.js
ファイルを作成し、次のコードスニペットを含めます:
const mongoose = require("mongoose");
const userSchema = new mongoose.Schema(
{
email: {
type: String,
lowercase: true,
required: true,
},
favouriteEmoji: {
type: String,
required: true,
},
yearOfBirth: {
type: Number,
required: true,
},
},
{
timestamps: true,
}
);
module.exports.UserModel = mongoose.model("User", userSchema);
2. ts-migrate-mongooseでマイグレーションスクリプトを作成します
ts-migrate-mongooseは、マイグレーションスクリプトを作成するために使用できるCLIコマンドを提供しています。
プロジェクトのルートフォルダでnpx migrate create <name-of-script>
を実行すると、MIGRATE_MIGRATIONS_PATH
フォルダ(この場合は./migrations
)にスクリプトが作成されます。<name-of-script>
は、作成されるマイグレーションスクリプトファイルの名前です。
ユーザーデータをシードするためのマイグレーションスクリプトを作成するには、次を実行します:
npx migrate create seed-users
このコマンドにより、./migrations
フォルダに、形式<timestamp>-seed-users.ts
の名前のファイルが作成されます。ファイルには次のコードスニペットの内容が含まれます:
// ここでモデルをインポートします
export async function up (): Promise<void> {
// マイグレーションを記述します
}
export async function down (): Promise<void> {
// マイグレーションを記述します
}
up
関数はマイグレーションを実行するために使用されます。 down
関数は、必要に応じてup
関数が実行したことを元に戻すために使用されます。 私たちの場合、データベースにユーザーをシードしようとしています。 up
関数には、データベースにユーザーをシードするコードが含まれ、down
関数にはup
関数で作成されたユーザーを削除するコードが含まれます。
データベースがMongoDB Compassで検査されると、マイグレーションコレクションには次のようなドキュメントが表示されます:
{
"_id": ObjectId("6744740465519c3bd9c1a7d1"),
"name": "seed-users",
"state": "down",
"createdAt": 2024-11-25T12:56:36.316+00:00,
"updatedAt": 2024-11-25T12:56:36.316+00:00,
"__v": 0
}
マイグレーションドキュメントのstate
フィールドはdown
に設定されています。 正常に実行されると、up
に変更されます。
./migrations/<timestamp>-seed-users.ts
内のコードを以下のスニペットのものに更新できます:
require("dotenv").config() // 環境変数をロード
const db = require("../db.js")
const { UserModel } = require("../user.model.js");
const seedUsers = [
{ email: "[email protected]", favouriteEmoji: "🏃", yearOfBirth: 1997 },
{ email: "[email protected]", favouriteEmoji: "🍏", yearOfBirth: 1998 },
];
export async function up (): Promise<void> {
await db.connect(process.env.MONGO_URI)
await UserModel.create(seedUsers);}
export async function down (): Promise<void> {
await db.connect(process.env.MONGO_URI)
await UserModel.delete({
email: {
$in: seedUsers.map((u) => u.email),
},
});
}
3. アプリケーションの開始前にマイグレーションを実行
ts-migrate-mongooseは、マイグレーションスクリプトのup
およびdown
関数を実行するためのCLIコマンドを提供してくれます。
npx migrate up <name-of-script>
で特定のスクリプトのup
関数を実行できます。 npx migrate up
で、データベースのstate
がdown
のすべてのスクリプトのup
関数を./migrations
フォルダー内で実行できます。
アプリケーションの開始前にマイグレーションを実行するには、npmスクリプトを利用します。 pre
接頭辞を持つnpmスクリプトは、pre
接頭辞のないスクリプトよりも前に実行されます。 たとえば、dev
スクリプトと predev
スクリプトがある場合、dev
スクリプトが npm run dev
で実行されると、dev
スクリプトが実行される前に predev
スクリプトが自動的に実行されます。
このnpmスクリプトの機能を利用して、マイグレーションが start
スクリプトの前に実行されるように、prestart
スクリプトに ts-migrate-mongoose コマンドを配置します。
package.json
ファイルを更新し、プロジェクト内のマイグレーションスクリプトの up
関数を実行するための prestart
スクリプトを追加します。
"scripts": {
"prestart": "npx migrate up",
"start": "node index.js"
},
このセットアップでは、アプリケーションを起動するために npm run start
を実行すると、prestart
スクリプトが実行され、ts-migrate-mongoose を使用してマイグレーションを実行し、データベースにシードを追加します。
npm run start
を実行した後、以下のスニペットのようなものが表示されるはずです:
Synchronizing database with file system migrations...
MongoDB connection successful
up: 1732543529744-seed-users.ts
All migrations finished successfully
> [email protected] start
> node index.js
MongoDB connection successful
Server listening on port 8000
この記事のこの時点でのコードベースの現在の状態を確認するには、リポジトリの seed-users ブランチをチェックしてください。
シードデータをフェッチするAPIエンドポイントを構築する方法
データベース内のシードユーザーデータを取得するためのAPIエンドポイントを構築できます。 server.js
ファイルで、以下のスニペットのコードに更新します:
const { UserModel } = require("./user.model.js")
module.exports = async function (req, res) {
const users = await UserModel.find({}) // データベース内のすべてのユーザーを取得
res.writeHead(200, { "Content-Type": "application/json" });
return res.end(JSON.stringify({ // 取得したユーザーデータのJSON表現を返す
users: users.map((u) => ({
email: u.email,
favouriteEmoji: u.favouriteEmoji,
yearOfBirth: u.yearOfBirth,
createdAt: u.createdAt
}))
}, null, 2));
};
アプリケーションを起動し、Postmanやブラウザを使用してhttp://localhost:8000を訪れると、以下のようなJSON応答を受け取ります:
{
"users": [
{
"email": "[email protected]",
"favouriteEmoji": "🏃",
"yearOfBirth": 1997,
"createdAt": "2024-11-25T14:18:55.416Z"
},
{
"email": "[email protected]",
"favouriteEmoji": "🍏",
"yearOfBirth": 1998,
"createdAt": "2024-11-25T14:18:55.416Z"
}
]
}
アプリケーションを再度実行すると、移行スクリプトはもはや実行されません。なぜなら、移行のstate
は実行が成功した後にup
になるからです。
この記事のこの時点でのコードベースの現在の状態を確認するには、リポジトリのfetch-usersブランチをチェックしてください。
結論
アプリケーションを構築する際に、テスト用の初期データをシードしたり、管理者ユーザーをシードしたり、列を追加または削除してデータベーススキーマを更新したり、複数のレコードの列の値を一度に更新する必要がある場合、マイグレーションは役立ちます。
ts-migrate-mongooseは、MongooseとMongoDBを使用している場合に、Node.jsアプリケーション用のマイグレーションを実行するためのフレームワークを提供するのに役立ちます。
Source:
https://www.freecodecamp.org/news/handle-mongodb-migrations-with-ts-migrate-mongoose/