Typescript 製の ORM TypeORM を試してみた。

こんにちは。k-jun です。本日は TypeScript 用の ORM、TypeORM を試してみます。

https://github.com/typeorm/typeorm

ORM は Golang とか Python のものはさんざん触ってきましたが、TypeScript は初ですね。 公式の README に従って、プロジェクトを作成してみます。

$ npm install typeorm -g
$ typeorm init --name MyProject --database mysql

$ tree
.
├── README.md
├── ormconfig.json
├── package.json
├── src
│   ├── entity
│   │   └── User.ts
│   ├── index.ts
│   └── migration
└── tsconfig.json
$ npm install

次に、ディレクトリ内に存在する ormconfig.json 見てみると以下のような内容。別に更新しても良いのですがめんどくさいので、この情報のママ接続できる MySQL を構築していきます。

$ cat ormconfig.json
{
   "type": "mysql",
   "host": "localhost",
   "port": 3306,
   "username": "test",
   "password": "test",
   "database": "test",
   "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"
   }
}

Docker で起動。あとは、npm start すればいいだけみたい。

$ docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -e MYSQL_USER=test -e MYSQL_PASSWORD=test -e MYSQL_DATABASE=test -d mysql:5.7
$ npm start

> MyProject@0.0.1 start
> 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.

Model が作成されてデータがインサートされたみたい。Golang などの ORM よりは Mongo とか Active Record 寄りの ORM だなぁ...。 Default の User モデル以外にも 追加してみる。

@Entity()
export class Todo {
    @PrimaryGeneratedColumn("uuid")
    id: string;
    @Column()
    title: string;
    @Column()
    body: string;
    @Column()
    isDone: boolean;
}

コードを書き換えて、起動してみる。

import "reflect-metadata";
import { createConnection } from "typeorm";
import { User, Todo } from "./entity/User";

createConnection().then(async connection => {

    const todo = new Todo();
    todo.title = "my blog"
    todo.body = "write article"
    todo.isDone = true
    await connection.manager.save(todo);

}).catch(error => console.log(error));
$ npm start
$ mysql -uroot -proot -h 127.0.0.1 -D test -e 'show create table `todo`\G'
mysql: [Warning] Using a password on the command line interface can be insecure.
*************************** 1. row ***************************
       Table: todo
Create Table: CREATE TABLE `todo` (
  `id` char(36) NOT NULL,
  `title` varchar(255) NOT NULL,
  `body` varchar(255) NOT NULL,
  `isDone` tinyint(4) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
$ mysql -uroot -proot -h 127.0.0.1 -D test -e 'select * from todo;'
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------------------------------------+---------+---------------+--------+
| id                                   | title   | body          | isDone |
+--------------------------------------+---------+---------------+--------+
| 60b6da5c-169b-4264-ad1c-905c4e44eed3 | my blog | write article |      1 |
+--------------------------------------+---------+---------------+--------+

良さそう!createConnection をした瞬間に、作成されていない Table は自動で作成されるみたい。 となるとやっぱり、Database との依存関係が切れないのである程度重い ORM となることは免れなさそう。

しかし、大きめのプロジェクトでは十分実用に耐えそうだし、便利そう。 次はもう少し軽めの TypeScript ORM を 試してみます。

それではこのへんで!