Skip to content

Seeds ​

Seeders populate your database with initial or test data. They are async classes that can call other seeders, making it easy to compose complex datasets from focused, single-responsibility classes.

Creating a Seeder ​

Place seeder files in databases/seeds/. Extend Seeder and implement an async run method:

python
# databases/seeds/user_seeder.py
from fastapi_startkit.masoniteorm.seeds import Seeder
from app.models.user import User

class UserSeeder(Seeder):
    async def run(self):
        await User.first_or_create(
            {"email": "admin@example.com"},
            {"name": "Admin User", "password": "secret"}
        )
        await User.first_or_create(
            {"email": "john@example.com"},
            {"name": "John Doe", "password": "secret"}
        )

Using first_or_create makes seeders idempotent — running them multiple times will not create duplicate records.

Database Seeder (Entry Point) ​

Create a DatabaseSeeder that calls your individual seeders in the correct order:

python
# databases/seeds/database_seeder.py
from fastapi_startkit.masoniteorm.seeds import Seeder
from .user_seeder import UserSeeder
from .post_seeder import PostSeeder

class DatabaseSeeder(Seeder):
    async def run(self):
        await self.call(UserSeeder)
        await self.call(PostSeeder)

self.call runs a seeder and waits for it to complete before continuing. Order matters when seeders have dependencies (e.g. posts require users to exist first).

Complete Example ​

The blog example seeds users, tags, posts, and pivot records:

python
# databases/seeds/post_seeder.py
from fastapi_startkit.masoniteorm.seeds import Seeder
from app.models import Post, User, Tag, PostTag

class PostSeeder(Seeder):
    async def run(self):
        user = await User.first()
        if not user:
            return

        # Create tags
        tag_python   = await Tag.first_or_create({"name": "python"})
        tag_fastapi  = await Tag.first_or_create({"name": "fastapi"})
        tag_database = await Tag.first_or_create({"name": "database"})

        # Create first post and attach tags
        post1 = await Post.create(
            user_id=user.id,
            title="Python and Databases",
            content="This is a post about Python and its database capabilities."
        )
        await PostTag.first_or_create({"post_id": post1.id, "tag_id": tag_python.id})
        await PostTag.first_or_create({"post_id": post1.id, "tag_id": tag_database.id})

        # Create second post and attach tags
        post2 = await Post.create(
            user_id=user.id,
            title="FastAPI and Databases",
            content="This is a post about FastAPI performance and database handling."
        )
        await PostTag.first_or_create({"post_id": post2.id, "tag_id": tag_fastapi.id})
        await PostTag.first_or_create({"post_id": post2.id, "tag_id": tag_database.id})

Running Seeds ​

Run all seeds via the DatabaseSeeder entry point:

bash
uv run python artisan db:seed

To run a specific seeder class:

bash
uv run python artisan db:seed --class UserSeeder