Database: Seeding
Introduction​
Stability: 2 - Stable
TinyORM includes the ability to seed your database with data using seed classes. All seed classes should be stored in the database/seeders
directory. The DatabaseSeeder
class is considered as the root seeder. From this class, you may use the call
method to run other seed classes, allowing you to control the seeding order.
Mass assignment protection is automatically disabled during database seeding.
Writing Seeders​
To generate a seeder, execute the make:seeder
tom
command. A new seeder will be placed in the database/seeders
directory relative to the current pwd:
tom make:seeder UserSeeder
You can omit the Seeder
word in the class name, tom
appends it for you.
A seeder class only contains one method by default: run
. This method is called when the db:seed
tom 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.
As an example, let's modify the default DatabaseSeeder
class and add a database insert statement to the run
method:
#pragma once
#include <tom/seeder.hpp>
namespace Seeders
{
/*! Main database seeder. */
struct DatabaseSeeder : Seeder
{
/*! Run the database seeders. */
void run() override
{
DB::table("users")->insert({"name", "email"},
{
{"1. user", "user1@example.com"},
{"2. user", "user2@example.com"},
});
}
};
} // namespace Seeders
The multi-insert insert
method overload is ideal for seeding data.
Calling Additional Seeders​
Within the DatabaseSeeder
class, you may 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 too large. The call
method accepts the template parameter pack of seeder classes that should be executed:
/*! Run the database seeders. */
void run() override
{
call<UserSeeder, PostSeeder, CommentSeeder>();
}
Call with additional arguments​
The call
method allows to pass additional arguments to the seeder/s, but it has additional requirements.
If you define a run
method without parameters then this method is called using the virtual dispatch (polymorphism) and in this case, you should use the override
specifier.
If you define your run
method eg. like this run(bool shouldSeed)
or whatever parameters you want, then this method is called using the fold expression (virtual dispatch is not used in this case) so you can't use the override
specifier and you must call the call<>()
method with exactly the same arguments like the run
method was defined with, in our example, it should look like this call<ExampleSeeder>(true)
.
Let's demonstrate it on a small example, following is the run
method in the root DatabaseSeeder
class.
/*! Run the database seeders. */
void run() override
{
// This value can be based eg. on data from the database
const auto shouldSeed = true;
call<UserSeeder>(shouldSeed);
}
The run
method in the UserSeeder
class.
/*! Run the database seeders. */
void run(const bool shouldSeed)
{
if (!shouldSeed)
return;
DB::table("users")->insert({
{"name", "1. user"},
});
}
The call
method provides two shortcut methods, callWith
and callSilent
(no output from seeders).
Running Seeders​
You may execute the db:seed
tom command to seed your database. By default, the db:seed
command runs the Seeders::DatabaseSeeder
class, which may in turn invoke other seed classes. However, you may use the --class
option to specify a specific seeder class to run individually:
tom db:seed
tom db:seed --class=UserSeeder
You may also seed your database using the migrate
, migrate:fresh
or migrate:refresh
commands in combination with the --seed
option. For example the migrate:fresh
command drops all tables and re-run all of your migrations. This command is useful for completely re-building your database:
tom migrate:fresh --seed
You can change the default seeders path as is described in the C preprocessor macros
, CMake provides the TOM_SEEDERS_DIR
option.
Forcing Seeders To Run In Production​
Some seeding operations may cause you to alter or lose data. In order to protect you from running seeding commands against your production database, you will be prompted for confirmation before the seeders are executed in the production
environment. To force the seeders to run without a prompt, use the --force
flag:
tom db:seed --force