📋
SaveYourTime
  • SaveYourTime - Coding Notes
  • Front-End
    • Next.js - Set up with TypeScript
  • Backend
    • Install MySQL on Ubuntu
    • Setup Certbot with route53 on Ubuntu 20.04
    • Configure a Nginx HTTPS Reverse Proxy
    • TypeORM - How to seed data with typeorm-seeding 🔥
  • React Native
    • React Native - Facebook Login
    • React Native - Adding a new Swift file and a Bridge header
  • Tools
    • ESLint
    • Prettier
  • Amazon Web Services
    • AWS - Deploy Next.js Application to AWS S3
    • AWS - Deploy Nest.js Server to Elastic Beanstalk
    • AWS - Setup AWS CloudFront
    • AWS - Configure HTTPS for CloudFront with GoDaddy Domain
    • AWS - Configure HTTPS for Elastic Beanstalk Environments with GoDaddy Domain
    • AWS - Fix Next.js static site hosted on S3 CloudFront routing fails on page reload
    • AWS - Running Puppeteer on AWS EC2
    • AWS - Running Metabase on AWS Elastic Beanstalk
  • GitHub Actions
    • Github - Deploying a React Next.js App to AWS S3 with Github Actions
    • Github - Deploying a Nest.js App to AWS Elastic Beanstalk (Docker Platform) with Github Actions
    • Github - Deploying a Nest.js App to AWS Elastic Beanstalk (Node.js Platform) with Github Actions
  • Others
    • Using Fastlane to automate beta deployments and releases for your iOS and Android apps
    • NodeBB
Powered by GitBook
On this page
  • Steps
  • Installation
  • What do we need?
  • Build our first Factory
  • Create our CreateUsers Seeder
  • Entity Factory
  • Seed data to our database
  • Run the script to seed data
  • Caution
  • Reference

Was this helpful?

  1. Backend

TypeORM - How to seed data with typeorm-seeding 🔥

Learn how to seed data with typeorm-seeding

PreviousConfigure a Nginx HTTPS Reverse ProxyNextReact Native - Facebook Login

Last updated 4 years ago

Was this helpful?

當你在進行專案開發(Development)時,通常資料庫裡面都需要一些進行測試用的假資料(Fake data);或者,專案上線(Production)時,會需要有一些 metadata 在裡面。例如:角色(Roles)、權限(Permissions)...等等。

此時,你有兩種方式餵資料給資料庫。第一種,手動新增(Manually);第二種,寫程式自動化(Automatically)新增,也就是我想介紹給大家的方式。

然而,寫程式自動化新增也有很多途徑,如果有上網做過功課的,看見最多的教學文件應該是使用 。由於,跟 migration 相關的教學文章(如:)已經有太多了,我就不多加介紹。在這邊我想介紹另一種方式,使用 和 這兩個套件,幫助我們餵資料給資料庫。

Faker 是一個幫助我們產生假資料的套件,有許多方法可以使用。 例如:faker.name.lastName(), faker.internet.email(), faker.phone.phoneNumber()

Steps

  1. Install typeorm-seeding, @types/faker (Optional, if you're using TypeScript)

  2. Setup seeds and factories

  3. Run seeder script with ormconfig

這邊假設,你已經有 Entity 了。 例如:user.entity.ts, pet.entity.ts, role.entity.ts

Installation

npm i typeorm-seeding
# or
yarn add typeorm-seeding

Optional, if you're using TypeScript

npm install -D @types/faker

We don't need to installfaker manually, because it's a dependency as typeorm-seeding.

What do we need?

  1. Seeds

  2. Factories

我們的資料夾結構(Folder Structure)如下:

  • src

    • database

      • seeds

        • create-user.seed.ts

      • factories

        • user.factory.ts

    • user

      • user.entity.ts

  • ormconfig.js

It is important that naming these files suffixed with .seed.ts and .factory.ts

例如:src/database/factories/user.factory.ts

Build our first Factory

src/database/factories/user.factory.ts

我們使用 typeorm-seeding 提供的方法 define 定義 Factory。 Factory 的主要目的是:利用資料(fake data)來產生實體(Entity)。

第一個參數為:Entity 第二個參數為:FactoryFunction,接收 faker 和 context 這兩個參數。

faker:主要用來產生假資料。 context:則是呼叫此 factory 時,用來接收傳遞下來的參數。在這個範例中,我並沒有用到。

export enum Gender {
  MALE = 'MALE',
  FEMALE = 'FEMALE',
  DIVERSE = 'DIVERSE',
}
import Faker from 'faker';
import { define } from 'typeorm-seeding';
import { User } from '../../users/user.entity';
import { Gender } from '../../users/gender.enum';

define(User, (faker: typeof Faker) => {
  const firstName = faker.name.firstName();
  const lastName = faker.name.lastName();
  const email = faker.internet.exampleEmail(firstName, lastName);
  const phone = faker.phone.phoneNumber();
  const address = faker.address.streetAddress();
  const dateOfBirth = faker.date.past();
  const gender = faker.random.objectElement<Gender>(Gender);

  const user = new User();
  user.firstName = firstName;
  user.lastName = lastName;
  user.gender = gender;
  user.email = email;
  user.phone = phone;
  user.address = address;
  user.dateOfBirth = dateOfBirth;
  return user;
});

Create our CreateUsers Seeder

src/database/seeds/create-user.seed.ts

有了 Factory 之後,我們可以來建立我們的 Seeder 了。 Seeder 是我們利用 factory 產生假資料,並寫入資料庫的地方。

首先,我們需要將我們的 CreateUser Seeder 用 implements 實踐來自 typeorm-seeding 的 Seeder。 接著我們就可以使用 Seeder 預設提供的一個 run 方法(method),和 define 一樣,提供兩個參數。

第一個參數為:Factory,透過呼叫 factory()() 來產生實體(Entity)並取得 EntityFactory。(HOF 用法) 第二個參數為:Connection,來自 typeorm 的 Connection。在這個範例中,我並沒有用到。

factory:第一個 () 接收 Entity,第二個 () 接收自定義的內容,自定義的內容會被傳送到 Factory 的第二個參數 context 中。例如:factory(User)('Hi, my name is Aaron')

import { Factory, Seeder } from 'typeorm-seeding';
import { User } from '../../users/user.entity';

export default class CreateUsers implements Seeder {
  public async run(factory: Factory): Promise<void> {
    await factory(User)().createMany(10);
  }
}

當你有多個 seed 檔案時,預設執行順序將按照字母順序執行。

Entity Factory

Entity Factory 透過執行 factory(User)() 後取得,他是一個已經跟 Entity 結合的 Factory,可以用來將實體寫入資料庫。

提供了幾個方法(method),例如:map, create, createMany, make, makeMany。

const userEntityFactory = factory(User)();
await userEntityFactory.create();
await userEntityFactory.createMany(10);
await userEntityFactory.make();
await userEntityFactory.makeMany(10);

create 與 make 最大的差別在於,create 會將資料寫入資料庫,而 make 不會。

Seed data to our database

當我們的 Factory 與 Seeder 都設定好了之後,我們就可以餵資料到資料庫了!

首先,我們需要告訴 typeorm-seeder,我們的 seeds 跟 factories 在哪裡,在你的 ormconfig.js 加入...

ormconfig.js

module.exports = {
  ...
  seeds: ['src/seeds/**/*{.ts,.js}'],
  factories: ['src/factories/**/*{.ts,.js}'],
}

接著,就可以執行 seed 的指令了。為了方便我們將指令加入 scripts 中。

package.json

"scripts": {
  "seed:config": "ts-node ./node_modules/typeorm-seeding/dist/cli.js config"
  "seed:run": "ts-node ./node_modules/typeorm-seeding/dist/cli.js seed"
  ...
}

Run the script to seed data

最後就可以用程式自動化餵資料到資料庫啦~🔥

npm run seed:run
# or
yarn seed:run

Caution

預設你的 ormconfig.js 在專案的根目錄中,而且名稱為 ormconfig.js

如果路徑與檔名不一樣,則可以透過 --configName (or -n) 與 --root (or -r),指定檔案位置與檔案名稱。

假設你的 ormconfig.js 放在 src/config/ormconfig.js,則需設定為...

-n ./src/config/ormconfig.js

"scripts": {
  "seed:config": "ts-node ./node_modules/typeorm-seeding/dist/cli.js config -n ./src/config/ormconfig.js",
  "seed:run": "ts-node ./node_modules/typeorm-seeding/dist/cli.js seed -n ./src/config/ormconfig.js"
  ...
}

經測試過後發現--root 跟想像中的設定有落差。若使用 -r 則會噴以下錯誤。

-r ./src/config (Don't do this!)

"scripts": {
  "seed:config": "ts-node ./node_modules/typeorm-seeding/dist/cli.js config -r ./src/config",
  "seed:run": "ts-node ./node_modules/typeorm-seeding/dist/cli.js seed -r ./src/config"
  ...
}

Reference

詳細用法,請查閱:

EntityFactory
https://github.com/w3tecch/typeorm-seeding
https://github.com/marak/Faker.js/
migration
How to seed TypeORM
typeorm-seeding
faker