Pop PHP
Database

Seeding

A seed puts known data into a database — the reference rows an application needs to boot, or a fixture to develop against. Seeds live beside migrations, one directory per connection, and Kettle runs them.

Writing a Seeder#

A seeder is a class extending Pop\Db\Sql\Seeder\AbstractSeeder with a single run() that receives the adapter. ./kettle db:create-seed SeedWidgets writes the template into database/seeds/<database>/, and unlike migrate:create it leaves the class name alone:

PHPdatabase/seeds/default/20260101120000_seed_widgets.php
<?php
declare(strict_types=1);

use Pop\Db\Adapter\AbstractAdapter;
use Pop\Db\Sql\Seeder\AbstractSeeder;

class SeedWidgets extends AbstractSeeder
{

    public function run(AbstractAdapter $db): void
    {
        $schema = $db->createSchema();
        $schema->create('widgets')
            ->int('id', 16)->increment()
            ->varchar('name', 255)->notNullable()
            ->primary('id');
        $schema->execute();

        $sql = $db->createSql();
        $sql->insert('widgets')->values(['name' => ':name']);

        foreach (['sprocket', 'flange', 'gizmo'] as $name) {
            $db->insert($sql, ['name' => $name]);
        }
    }

}

$db is a full adapter, so a seeder has the schema builder, the query builder and raw queries all available — build the table and fill it in one run(), as above, or fill a table a migration already created.

SQL Seed Files#

A plain .sql file in the same directory works too, and is the better shape for a fixture you exported rather than wrote. SQL Data covers producing one from rows you already have.

Running Seeds#

BASH
./kettle db:create-seed SeedWidgets
./kettle db:seed
./kettle db:seed all

db:seed runs everything in the directory — .sql files through Pop\Db\Db::executeSqlFile(), seeder classes by instantiating them and calling run(). Like the migrate: commands, the optional <database> argument picks a connection directory, default when you leave it off and all for every one in turn.

db:seed empties the database before it seeds, so point it at a development connection.

A seeder is an ordinary class, so anything else can run one directly — a test fixture, or a setup command of your own:

PHP
use Pop\Db\Record;

$seeder = new SeedWidgets();
$seeder->run(Record::getDb());

See Also#

  • Migrations — the schema the seeded rows go into, and the directories seeds sit beside
  • SQL Data — turning existing rows into the .sql file this page runs
  • Schema BuildercreateSchema() inside a seeder's run()
  • Kettle — the command runner db:seed belongs to
  • pop-db README — the seeder API surface