Seeding

Introduction

Orator includes a simple method of seeding your database with test data using seed classes. Seed classes may have any name you wish, but probably should follow some sensible convention, such as UsersTableSeeder, etc. By default, a DatabaseSeeder class is defined for you the first time you create a seed class. From this class, you can use the call method to run other seed classes, allowing you to control the seeding order.

Writing Seeders

To generate a seeder, you may issue the seeders:make command. All seeders generated by the command will be placed in a seeders directory relative to where the command has been executed:

orator seeds:make user_table_seeder

Note

If you want the seed classes to be stored in another directory, use the -p/--path option

A seeder class only contains one method by default: run. This method is called when the db:seed command is executed. Within the run method, you can insert data into your database however you wish. You can use the Query Builder to manually insert data or you can use Model Factories.

As an example, let’s modify the UsersTableSeeder class you just created. Let’s add a database insert statement to the run method:

from orator.seeds import Seeder


class UsersTableSeeder(Seeder):

    def run(self):
        """
        Run the database seeds.
        """

        # Here you could just use random string generators
        # rather than hardcoded values
        self.db.table('users').insert({
            'name': 'john',
            'email': 'john@doe.com'
        })

Using Model Factories

Of course, manually specifying the attributes for each model seed is cumbersome. Instead, you can use Model Factories to conveniently generate large amounts of database records. First, review the model factory documentation to learn how to define your factories. You can use an external factory or use the seeder class factory attribute.

For example, let’s create 50 users and attach a relationship to each user:

from orator.seeds import Seeder
from orator.orm import Factory


factory = Factory()


@factory.define(User)
def users_factory(faker):
    return {
        'name': faker.name(),
        'email': faker.email()
    }


@factory.define(Post)
def posts_factory(faker):
    return {
        'title': faker.name(),
        'content': faker.text()
    }


class UsersTableSeeder(Seeder):

    factory = factory  # This is only needed when using an external factory

    def run(self):
        """
        Run the database seeds.
        """
        self.factory(User, 50).create().each(
            lambda u: u.posts().save(self.factory(Post).make())
        )

Or using directly the factory attribute without an external factory:

class UsersTableSeeder(Seeder):

    def run(self):
        """
        Run the database seeds.
        """
        self.factory.register(User, self.users_factory)
        self.factory.register(Post, self.posts_factory)

        self.factory(User, 50).create().each(
            lambda u: u.posts().save(self.factory(Post).make())
        )

    def users_factory(self, faker):
        return {
            'name': faker.name(),
            'email': faker.email()
        }

    def posts_factory(self, faker):
        return {
            'title': faker.name(),
            'content': faker.text()
        }

Calling Additional Seeders

Within the DatabaseSeeder class, you can use the call method to execute additional seed classes. Using the call method allows you to break up your database seeding into multiple files so that no single seeder class becomes overwhelmingly large. Simply pass the seeder class you wish to run:

def run(self):
    """
    Run the database seeds.
    """
    self.call(UsersTableSeeder)
    self.call(PostsTableSeeder)
    self.call(CommentsTableSeeder)

Running Seeders

Once you have written your seeder classes, you may use the db:seed command to seed your database. By default, the db:seed command runs the database_seeder file, which can be used to call other seed classes. However, you can use the --seeder option to specify a specific seeder class to run individually:

orator db:seed

orator db:seed --seeder users_table_seeder

You can also seed your database using the migrations:refresh command, which will also rollback and re-run all of your migrations. This command is useful for completely re-building your database:

orator migrations:refresh --seed