typeormの設定をormconfig.tsから読み込む
概要
typeorm の設定ファイルはデフォルトで、ormcofig.json ですが、このままだと以下の問題点があると考えます。
- 環境変数を埋め込みづらい
- プロジェクトのルートディレクトリにファイルが増える
- 自動で読み込まれるのでデバッグしづらい
環境変数を読み込むには ts ファイルの方が楽ですし、ほかの config とまとめることができるので、ormconfig.ts から読み込む方法を記述します。
環境構築の方法は、以下の記事を参考にしていただきたいです(Node.js 14.17.0 をインストールまで)。
完成したソースコードは以下です。
環境構築
typeorm init
ディレクトリを作成します。
mkdir typeorm_ormcofig.ts_example
cd typeorm_ormcofig.ts_example
typerom init
で typeorm の構成を自動生成できます。
typerom を使う時に必須ではないですが、簡略化のため使用しました。
DB は MySQL を使用しました。
npx typeorm init --database mysql
生成されるファイル構成は以下(node_modules は除外して表示)になります。
tree -I node_modules
.
├── README.md
├── ormconfig.json
├── package-lock.json
├── package.json
├── src
│ ├── entity
│ │ └── User.ts
│ ├── index.ts
│ └── migration
└── tsconfig.json
3 directories, 7 files
MySQL サーバ をコンテナで作成
docker compose
Docker で、MySQL サーバを作成します。
プロジェクトのルートディレクトリにdocker-compose.yml
を作成します。
version: "3.5"
services:
db:
image: mysql:5.7.34
container_name: mysql-container
environment:
MYSQL_DATABASE: "typeorm_db"
MYSQL_ROOT_PASSWORD: "password"
restart: "always"
ports:
- "3306:3306"
MySQL へ接続を確認
コンテナを起動。
docker compose up -d
接続確認。パスワードはdocker-compose.yml
に記述したpassword
、typeorm_db
になります。
ログインできたら成功です。
mysql -u root --port 3306 -h 127.0.0.1 -D typeorm_db -p
.env ファイルを作成
プロジェクトのルートディレクトリに.env
ファイルを作成します。
.env
# DB
DB_HOST=127.0.0.1
DB_PORT=3306
DB_USERNAME=root
DB_PASSWORD=password
DB_DATABASE=typeorm_db
.env ファイルを.gitignore に追加します。
.idea/
.vscode/
node_modules/
build/
tmp/
temp/
# 追加
.env
以下のコマンドで読み込む。
export $(cat .env | grep -v ^# | xargs)
実装
ormconfig.ts を作成
src/config
ディレクトリを作成し、src/config/ormconfig.ts
ファイルを作成します。
記述内容は以下になります。
/** 全て追加 **/
import { ConnectionOptions } from "typeorm";
const ormconfig: ConnectionOptions = {
type: "mysql",
host: process.env.DB_HOST,
port: parseInt(process.env.DB_PORT, 10),
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
synchronize: true,
logging: false,
entities: ["src/entity/**/*.ts"],
migrations: ["src/migration/**/*.ts"],
subscribers: ["src/subscriber/**/*.ts"],
cli: {
entitiesDir: "src/entity",
migrationsDir: "src/migration",
subscribersDir: "src/subscriber",
},
};
export default ormconfig;
ormconfig.json
は不要になったので削除します。
rm ormconfig.json
ormconfig.ts を読み込む
src/index.ts
を以下のように修正します。
import "reflect-metadata";
import { createConnection } from "typeorm";
import { User } from "./entity/User";
import connectionOption from "./config/ormconfig"; // 追加
createConnection(connectionOption) // 修正
.then(async (connection) => {
console.log("Inserting a new user into the database...");
const user = new User();
user.firstName = "Timber";
user.lastName = "Saw";
user.age = 25;
await connection.manager.save(user);
console.log("Saved a new user with id: " + user.id);
console.log("Loading users from the database...");
const users = await connection.manager.find(User);
console.log("Loaded users: ", users);
console.log("Here you can setup and run express/koa/any other framework.");
})
.catch((error) => console.log(error));
動作確認
MySQL でデータベースにはテーブルが存在しないことを確認
以下のコマンドで何も表示されないことを確認します。
mysql -u root --port 3306 -h 127.0.0.1 -D typeorm_db -e 'SHOW TABLES;' -p
migration ファイルを生成
migration:generate
で migration ファイルが生成されます。
-f で ormconfig.ts へのパスを書くのがポイントです。デフォルトではルートにある ormconfig.json を取得しようとします。
npx ts-node ./node_modules/.bin/typeorm migration:generate -n user -f ./src/config/ormconfig.ts
以下のような表示がされたら成功です。
Migration /PATH/TO/typeorm_ormcofig.ts_example/src/migration/1623800662217-user.ts has been generated successfully.
migration 実行
migration:run
で migration を実行できます。
以下のコマンドで typeorm_db データベースに user テーブルが追加されます。
npx ts-node ./node_modules/.bin/typeorm migration:run -f ./src/config/ormconfig.ts
query: SELECT * FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = 'typeorm_db' AND `TABLE_NAME` = 'migrations'
query: CREATE TABLE `typeorm_db`.`migrations` (`id` int NOT NULL AUTO_INCREMENT, `timestamp` bigint NOT NULL, `name` varchar(255) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB
query: SELECT * FROM `typeorm_db`.`migrations` `migrations` ORDER BY `id` DESC
0 migrations are already loaded in the database.
1 migrations were found in the source code.
1 migrations are new migrations that needs to be executed.
query: START TRANSACTION
query: CREATE TABLE `user` (`id` int NOT NULL AUTO_INCREMENT, `firstName` varchar(255) NOT NULL, `lastName` varchar(255) NOT NULL, `age` int NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB
query: INSERT INTO `typeorm_db`.`migrations`(`timestamp`, `name`) VALUES (?, ?) -- PARAMETERS: [1623800662217,"user1623800662217"]
Migration user1623800662217 has been executed successfully.
query: COMMIT
MySQL でテーブルを確認
さきほどと同じコマンドを実行して、テーブルが追加されていることを確認します。
mysql -u root --port 3306 -h 127.0.0.1 -D typeorm_db -e 'show tables;' -p
+----------------------+
| Tables_in_typeorm_db |
+----------------------+
| migrations |
| user |
+----------------------+
また、以下のコマンドで user テーブルにはカラムが存在しないことを確認できます。
実行してもなにも表示されません。
mysql -u root --port 3306 -h 127.0.0.1 -D typeorm_db -e 'SELECT * FROM user;' -p
user テーブルにカラムを追加。
typeorm init
では、src/index.ts
上でデータベースにカラムを追加する処理が含まれているので実行します、
実行後、ctrl + c
で停止しても大丈夫です。
ts-node ./src/index.ts
出力。
Inserting a new user into the database...
Saved a new user with id: 1
Loading users from the database...
Loaded users: [ User { id: 1, firstName: 'Timber', lastName: 'Saw', age: 25 } ]
Here you can setup and run express/koa/any other framework.
MySQL でカラムを確認
先ほどと同様にカラムを確認します。
カラム追加されたことがわかります。
mysql -u root --port 3306 -h 127.0.0.1 -D typeorm_db -e 'SELECT * FROM user;' -p
出力。
+----+-----------+----------+-----+
| id | firstName | lastName | age |
+----+-----------+----------+-----+
| 1 | Timber | Saw | 25 |
+----+-----------+----------+-----+
その他
typeorm の設定ファイルを ormconfig.json から、ormconfig.ts に変更する方法と動作確認について執筆しました。
一般的に使われる手法がどちらなのかはわからないので、設計を考えるときや一緒に作業する人と相談などして決めましょう。
また今回は、src/config/ormconfig.ts
にまとめましたが、src/config/index.ts
を作成して、ほかの設定とまとめても良いと思いました。
備考
DB 関連
MySQL に接続するコマンドを実行すると、エラーがでる
以下のエラーの場合、DB サーバが起動できていないです。もう少し待ったら動くようになります。
ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0
DB を永続化したい。
volume の設定を追加します。
以下は、一例です。
version: "3.5"
services:
db:
image: mysql:5.7.34
container_name: mysql-container
environment:
MYSQL_DATABASE: "typeorm_db"
MYSQL_ROOT_PASSWORD: "password"
restart: "always"
ports:
- "3306:3306"
volumes:
- ./.data/db:/var/lib/mysql
127.0.0.1
を指定するのか
DB に接続するときに、何も指定しないと、localhost:3306
に接続されてしまう現象を確認しています。自分も詳細は理解していませんが、
以下の記事が参考になりました。
TypeScript 関連
"mysql"
の箇所も環境変数にしたい。
以下の箇所ですが、型チェックで怒られて対処できていないです。
as なんとか
によって解決できそうですが、どなたか教えていただきたいです。
/** 全て追加 **/
import { ConnectionOptions } from "typeorm";
const ormconfig: ConnectionOptions = {
type: "mysql",
host: process.env.DB_HOST,
port: parseInt(process.env.DB_PORT, 10),
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
synchronize: true,
logging: false,
entities: ["src/entity/**/*.ts"],
migrations: ["src/migration/**/*.ts"],
subscribers: ["src/subscriber/**/*.ts"],
cli: {
entitiesDir: "src/entity",
migrationsDir: "src/migration",
subscribersDir: "src/subscriber",
},
};
export default ormconfig;
Discussion