Skip to main content

Database: Seeding

See how to create and run database seeders.

Introduction​

Athenna includes the ability to seed your database with data using seed classes. All seed classes are stored in the

Path.seeders()

./src/database/seeders

directory.

Writing seeders​

To generate a seeder, execute the make:seeder Artisan command. All seeders generated by the framework will be placed in the

Path.seeders()

./src/database/seeders

directory:

node artisan make:seeder UserSeeder

A seeder class only contains one method by default: run(). This method is called when the db:seed Artisan command is executed. Within the run() method, you may insert data into your database however you wish. You may use the query builder to manually insert data, or you may use the model factories:

import { User } from '#src/models/user'
import { BaseSeeder, type DatabaseImpl } from '@athenna/database'

export class UserSeeder extends BaseSeeder {
public async run(db: DatabaseImpl) {
await db.table('users').createMany([/*.....*/])

await User.factory().count(20).create()
}
}

Running seeders​

You may execute the db:seed Artisan command to seed your database. By default, the db:seed command will run all the seeders inside the

Path.seeders()

./src/database/seeders

folder, but you can run only one seeder using the --classes argument:

node artisan db:seed

node artisan db:seed --classes=UserSeeder

You can also run your seeders in a connection that is not the default one using the --connection option:

node artisan db:seed --connection=postgres
tip

Want to start from a clean database and seed it in one go? Use the db:fresh --with-seeders command. It wipes your database, runs your migrations and then your seeders. Check the migrations documentation for more details.

Seeders execution order​

Seeders run one after another, never at the same time. This means a seeder only starts when the previous one has finished, so you don't need to worry about two seeders fighting over the same table.

If one seeder depends on the data of another one (e.g. orders need users to exist first), the simplest way to guarantee the order is calling it explicitly from a "main" seeder:

import { UserSeeder } from './UserSeeder.js'
import { OrderSeeder } from './OrderSeeder.js'
import { BaseSeeder, type DatabaseImpl } from '@athenna/database'

export class DatabaseSeeder extends BaseSeeder {
public async run(db: DatabaseImpl) {
await new UserSeeder().run(db)
await new OrderSeeder().run(db)
}
}
node artisan db:seed --classes=DatabaseSeeder
caution

Remember that running db:seed without the --classes option runs all the seeders inside the

Path.seeders()

./src/database/seeders

folder. In the example above, this means UserSeeder and OrderSeeder would run twice: once by themselves and once again by DatabaseSeeder. When using a "main" seeder, always run it with --classes.

Setting the seeder connection​

If your seeder will be interacting with a database connection other than your application's default database connection, you should set the static method connection() in your seeder:

import { BaseSeeder, type DatabaseImpl } from '@athenna/database'

export class UserSeeder extends BaseSeeder {
public static connection() {
return 'postgres'
}

public async run(db: DatabaseImpl) {
await Database.table('users').createMany([/*.....*/])

await User.factory().count(20).create()
}
}