Using TypeORM migrations for simple database seeding (NestJS example)
This article describes a very simple way to populate an existing SQL database with an initial set of data. We will use TypeORM, TypeScript, and NestJS (just for examples). If you already set up your migrations you can immediately jump to the last section.
The TypeORM library comes with hundreds of useful features, but unfortunately, there’s no “seeding” tool built-in at the time of writing this article. There’s no need to install an additional package like typeorm-seeding if you need just a simple initial set of data to work with. You can use only built-in migration tools to achieve that.
Configuring migrations
First of all, you need to add some necessary parameters to your TypeORM configuration. You can skip this step if you already set up migrations. Here you can see an example of config for an SQLite database.
The migrations
parameter should point to the catalog to which the NestJS server will be built. If your technology stack doesn’t require a building process or just works differently, you need to adjust this path to your needs. The cli: { migrationsDir: ... }
points to our migration files.
Remember that you need to generate initial migrations which will prepare the database architecture, you can’t seed your database if it doesn’t have tables. You’ll need two commands to generate and run migrations, take a look at my package.json
:
"typeorm": "node --require ts-node/register ./node_modules/typeorm/cli.js","migration:generate": "npm run build && npm run typeorm migration:generate -- -n","migration:run": "npm run build && npm run typeorm migration:run"
We’re running npm run build
before specific TypeORM commands, because of the nature of NestJS. You have to adjust these commands to your needs if your technology stack requires additional steps as I mentioned earlier. The -- -n
flag allows us to name the migration.
Check out the TypeORM documentation to learn more about migrations. Take an especially close look at reverting migrations process which can save you a lot of time in the future.
Migration structure
Migrations generated by TypeORM are mostly made of raw SQL queries. TypeORM is creating a class that implements MigrationInterface and contains two methods: up and down. The up method contains the code to perform the migration. The down method is used to revert changes, and it’s helpful in case of error.
Migration file name is composed of three parts: a timestamp, dash character, and a name. TypeORM runs migration files from the oldest to the newest. To ensure that our Seed migration runs at the very end I’m giving it a timestamp that’s far in the future.
Seed the database
The up and down methods from the MigrationInterface have access to the QueryRunner object which is most often used to run raw SQL queries. You can use it to run a query, or you can access the manager to insert data conveniently using your models.
Here’s an example of adding a new row to the currency table:
I’m creating a new instance of CurrencyEntity using the create method and then immediately I’m saving it to the database using the save. I suppose you’re familiar with these methods. The save method returns the saved row, so you can later use it to seed tables that use relations.
TypeORM by default uses transactions while the execution of migrations, so there’s actually no real need to add them here. As you can see I’ve added also some code inside the down method. If the “Seeding” migration inserts wrong data you can easily revert the changes using this command which will run the down method:
typeorm migration:revert
Conclusion
Using migration tools you can easily seed your database with a small initial dataset, especially if you need it only for development purposes. For more sophisticated cases take a look at the typeorm-seeding package.