package
yarn add typeorm
yarn add -D babel-plugin-transform-typescript-metadata @babel/plugin-proposal-class-properties @babel/plugin-proposal-decorators ts-node
env
env.development.local
DATABASE_TYPE=mysql
DATABASE_HOST=localhost
DATABASE_PORT=3306
DATABASE_USERNAME=root
DATABASE_PASSWORD=
DATABASE_NAME=testdb
ormconfig.js
作成
ormconfig.js
require('dotenv').config({ path: '.env.development.local' });
module.exports = {
type: process.env.DATABASE_TYPE,
host: process.env.DATABASE_HOST,
port: process.env.DATABASE_PORT,
username: process.env.DATABASE_USERNAME,
password: process.env.DATABASE_PASSWORD,
database: process.env.DATABASE_NAME,
synchronize: false,
logging: true,
entities: ['db/entities/**/*.ts'],
migrations: ['db/migrations/**/*.ts'],
subscribers: ['db/subscribers/**/*.ts'],
cli: {
entitiesDir: 'db/entities',
migrationsDir: 'db/migrations',
subscribersDir: 'db/subscribers'
}
};
tsconfig.json
一部オプション追加
tsconfig.json
{
"compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
}
}
babel plugin 追加
.babelrc.js
module.exports = {
presets: ['next/babel'],
plugins: [
'babel-plugin-transform-typescript-metadata',
['@babel/plugin-proposal-decorators', { legacy: true }],
]
};
こうしないと吐かれるれるエラー
Syntax error: Support for the experimental syntax 'decorators-legacy' isn't currently enabled:
ColumnTypeUndefinedError: Column type for User#** is not defined and cannot be guessed. Make sure you have turned on an "emitDecoratorMetadata": true option in tsconfig.json. Also make sure you have imported "reflect-metadata" on top of the main entry file in your application (before any entity imported).If you are using JavaScript instead of TypeScript you must explicitly provide a column type.
Entity作成
db/entities/User.ts
import { Entity, BaseEntity, PrimaryGeneratedColumn, Column, OneToOne, JoinColumn } from 'typeorm';
import { UserProfile } from './index';
@Entity({ name: 'users' })
export class User extends BaseEntity {
@PrimaryGeneratedColumn()
readonly id: number;
@OneToOne(() => UserProfile, (userProfile: UserProfile) => userProfile.user)
@JoinColumn()
userProfile: UserProfile;
}
db/entities/UserProfile.ts
import {
Entity,
BaseEntity,
PrimaryGeneratedColumn,
Column,
OneToOne,
JoinColumn
} from 'typeorm';
import { User } from './index';
@Entity({ name: 'userProfiles' })
export class UserProfile extends BaseEntity {
@PrimaryGeneratedColumn()
readonly id: number;
@OneToOne(() => User, (user: User) => user.userProfile)
@JoinColumn()
user: User;
importするときは、以下のようにまとめてこのファイルからimportするようにしないとエラーになる
db/entities/index.ts
import { User } from './User';
import { UserProfile } from './UserProfile';
export { User, UserProfile };
こうしないと吐かれるれるエラー
ReferenceError: Cannot access 'User' before initialization
migration実行
package.json
package.json
{
"scripts": {
"typeorm": "ts-node ./node_modules/typeorm/cli.js",
"db:migrate:create": "yarn typeorm migration:generate -n",
"db:migrate:run": "yarn typeorm migration:run",
"db:reset:init": "yarn typeorm schema:drop; rm -rf db/migrations/*; yarn db:migrate:create init; yarn db:migrate:run"
}
}
yarn db:reset:init
connection
db/db.ts
import 'reflect-metadata';
import { getConnection, createConnection, Connection } from 'typeorm';
import { User, UserProfile } from '@db/entities';
const host = process.env.DATABASE_HOST || '';
const port = Number(process.env.DATABASE_PORT) || 3306;
const username = process.env.DATABASE_USERNAME || '';
const password = process.env.DATABASE_PASSWORD || '';
const database = process.env.DATABASE_NAME || '';
let connectionReadyPromise: Promise<Connection> | null = null;
export const prepareConnection = () => {
if (!connectionReadyPromise) {
connectionReadyPromise = (async () => {
// clean up old connection that references outdated hot-reload classes
try {
const staleConnection = getConnection();
await staleConnection.close();
} catch (error) {
// no stale connection to clean up
}
// wait for new default connection
const connection = await createConnection({
type: 'mysql',
host,
port,
username,
password,
database,
entities: [User, UserProfile],
synchronize: false,
logging: true
});
return connection;
})();
}
return connectionReadyPromise;
};
使い方
import { prepareConnection } from '@db/db';
import { User } from '@db/entities';
(async () => {
const db = await prepareConnection();
const user = await db.getRepository(User).find();
console.log(user);
})();