21
Take your database seeding to the next level with Faker.js
Database seeding is term used to describe the initial data population of database. the data is either a dummy data for testing or some initial necessary data.
We will use knex.js for our migrations and seeding. you can use any other library or method you want.
First let's instantiate Knex config file via Knex cli:
npx knex init
and then setup your Knex configuration in knexfile.js/ts
Now We will create user and post migrations via:
npx knex migrate:make users
npx knex migrate:make posts
A migrations files will be created in migrations folder(or your configured migrations folder).
Then set up your tables in the migration files. the final result will be something like:
//xxxxxxxxxxxx_users.js
/** @param {import("knex").Knex} knex */
exports.up = function(knex) {
return knex.schema.createTable("user", (table) => {
table.uuid("id").primary().defaultTo(knex.raw("gen_random_uuid()")); // gen_random_uuid is postgres only
table.string("username").unique().notNullable();
table.string("email").notNullable();
table.string("password").notNullable();
table.string("full_name").notNullable();
table.string("avatar");
table.timestamps(true, true); // created_at, updated_at
});
};
/** @param {import("knex").Knex} knex */
exports.down = function(knex) {
return knex.schema.dropTable("users");
};
//xxxxxxxxxxxx_posts.js
/** @param {import("knex").Knex} knex */
exports.up = function(knex) {
return knex.schema.createTable("posts", (table) => {
table.uuid("id").primary().defaultTo(knex.raw("gen_random_uuid()"));
table.uuid("author").notNullable().references("users.id");
table.text("title").notNullable();
table.text("content").notNullable();
table.integer("likes").notNullable().defaultTo(0);
table.timestamps(true, true); // created_at, updated_at
});
};
/** @param {import("knex").Knex} knex */
exports.down = function(knex) {
return knex.schema.dropTable("posts");
};
Then run npx knex migrate:latest
to run your migrations
After we setup the tables. We're ready for seeding. to create seeding file, run:
knex seed:make users
knex seed:make posts
This will create seeding files in seeding folder. each file has exported seed function. we will use that function generate the seeding data
Let's first create a function to generate our user object. so we can get an idea of user entry before inserting them to the databse:
we will use faker.helpers.contextualCard
. this function will generate some random user related info like username, full name, email, or even avatars!. the output of the function looks like:
{
"name": "Samanta",
"username": "Samanta22",
"avatar": "https://cdn.fakercloud.com/avatars/solid_color_128.jpg",
"email": "[email protected]",
"dob": "1970-04-17T02:17:28.907Z",
"phone": "350-910-3872 x539",
"address": {
"street": "Hudson Loaf",
"suite": "Suite 371",
"city": "Elodyborough",
"zipcode": "12496-9242",
"geo": {
"lat": "74.0449",
"lng": "-53.5555"
}
},
"website": "chance.org",
"company": {
"name": "West - Gislason",
"catchPhrase": "Managed tertiary utilisation",
"bs": "exploit dynamic blockchains"
}
}
we don't need all of that. so we will take in what we defined in the users table:
function generateRandomUser() {
const user = faker.helpers.contextualCard();
return {
username: user.username,
// password is required. so we need to throw any value to avoid errors.
// in real world scenario we will hash the password
password: "1234",
email: user.email,
full_name: user.name,
avatar: user.avatar,
};
}
Now we will use this function to generate multiples fake users:
const USER_COUNT = 10;
const TABLE_NAME = "users"
/** @param {import("knex").Knex} knex */
exports.seed = async function (knex) {
// Deletes ALL existing entries
await knex(TABLE_NAME).del();
// Inserts seed entries
return knex(TABLE_NAME).insert(
Array.from({ length: USER_COUNT }, () => {
return generateUser();
})
);
};
Now our users seeding is ready. but before run the seeding. we need to define some random user posts. so we will use the same approach:
const faker = require("faker");
const TABLE_NAME = "posts";
function randomArray(arr) {
return arr[
// We could use Math.random. but this function give us more less predicted numbers
faker.datatype.number({
max: Math.max(0, arr.length - 1)
})
];
}
function generateRandomPosts(author) {
return {
author, // author id
title: faker.lorem.sentence(), // random sentence.
content: faker.lorem.paragraph(), // random paragraph
likes: faker.datatype.number(1e6) // random likes count between 0 to 1m
};
}
const POST_COUNT = 1000; // specify your generated posts count
/** @param {import("knex").Knex} knex */
exports.seed = async function(knex) {
// delete all previous rows
await knex(TABLE_NAME).del();
// select some users from database. so we can create random posts from random users
const users = await knex.table("users").select().limit(50);
if (!users || !users.length) throw Error("Cannot find users");
const posts = Array.from({length: POST_COUNT}, async () => {
const user = randomArray(users); // to link the post to a random user
return generateRandomPosts(user.id);
});
return knex(TABLE_NAME).insert(posts); // now insert the generated data 🎉🥳
};
Finally. after you finish setting up your seeding data you can run all seeding via one command:
npx knex seed:run
Now your database test data is ready. your front-end dev will be happy😁
21