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.
To generate a seeder, you may issue the make:seed
command.
All seeders generated by the command will be placed in a seeds
directory
relative to where the command has been executed:
orator make:seed 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'
})
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()
}
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)
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