Best Practices#

Production-ready patterns and recommendations for Django Synced Seeds.

Seeder Design#

Keep It Simple#

  • One seeder per logical data group

  • Use descriptive seed_slug names

  • Avoid complex inheritance hierarchies

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# Good: Focused and clear
@seeder_registry.register()
class CategorySeeder(Seeder):
    seed_slug = "categories"
    exporting_querysets = (Category.objects.all(),)

# Avoid: Too broad and complex
class EverythingSeeder(Seeder):
    seed_slug = "everything"  # Too vague
    exporting_querysets = (
        User.objects.all(),
        Product.objects.all(),
        Order.objects.all(),  # Unrelated to categories
        # ... many more
    )

Data Relationships#

Handle related data carefully using priorities to ensure dependencies load first:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Use priority to control load order
@seeder_registry.register()
class CategorySeeder(Seeder):
    seed_slug = "categories"
    priority = 10  # Load first
    exporting_querysets = (Category.objects.all(),)

@seeder_registry.register()
class BrandSeeder(Seeder):
    seed_slug = "brands"
    priority = 10  # Load first (same priority as categories)
    exporting_querysets = (Brand.objects.all(),)

@seeder_registry.register()
class ProductSeeder(Seeder):
    seed_slug = "products"
    priority = 20  # Load after categories and brands
    exporting_querysets = (Product.objects.all(),)

@seeder_registry.register()
class ProductVariantSeeder(Seeder):
    seed_slug = "product_variants"
    priority = 30  # Load after products
    exporting_querysets = (ProductVariant.objects.all(),)

Priority Patterns for Foreign Keys#

When you have models with foreign key relationships, use priorities to prevent database integrity errors:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Example: E-commerce schema
# Country -> Region -> Store -> Employee

@seeder_registry.register()
class CountrySeeder(Seeder):
    seed_slug = "countries"
    priority = 1  # No dependencies
    exporting_querysets = (Country.objects.all(),)

@seeder_registry.register()
class RegionSeeder(Seeder):
    seed_slug = "regions"
    priority = 2  # Depends on Country
    exporting_querysets = (Region.objects.all(),)

@seeder_registry.register()
class StoreSeeder(Seeder):
    seed_slug = "stores"
    priority = 3  # Depends on Region
    exporting_querysets = (Store.objects.all(),)

@seeder_registry.register()
class EmployeeSeeder(Seeder):
    seed_slug = "employees"
    priority = 4  # Depends on Store
    exporting_querysets = (Employee.objects.all(),)

Tagging Strategy#

Use tags to organize seeders by purpose and environment:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Testing tags - organize by test type
@seeder_registry.register(tags="e2e")
class E2EUserSeeder(Seeder):
    seed_slug = "e2e_users"
    exporting_querysets = (User.objects.all(),)

@seeder_registry.register(tags=["integration", "e2e"])
class IntegrationTestSeeder(Seeder):
    seed_slug = "integration_data"
    exporting_querysets = (Product.objects.all(),)

# Environment tags - organize by deployment stage
@seeder_registry.register(tags="development")
class DevSampleDataSeeder(Seeder):
    seed_slug = "dev_samples"
    exporting_querysets = (Product.objects.all(),)

@seeder_registry.register(tags="demo")
class DemoSeeder(Seeder):
    seed_slug = "demo_showcase"
    exporting_querysets = (Product.objects.all(),)

# Data category tags - organize by data type
@seeder_registry.register(tags="base")
class BaseConfigSeeder(Seeder):
    seed_slug = "base_config"
    exporting_querysets = (
        Settings.objects.all(),
        Roles.objects.all(),
    )

Version Control#

Seed File Management#

  • Commit seed files to version control

  • Use meaningful commit messages

  • Tag releases that include seed updates

# Good commit practices
git add seeds/
git commit -m "feat(seeds): add initial product categories

- Add 12 main categories
- Include subcategories for electronics
- Update revision to v3"

# Tag important releases
git tag -a v1.2.0 -m "Release with updated seed data"

Branching Strategy#

  • Keep seed changes in feature branches

  • Review seed updates like code changes

  • Test seed updates in staging before production

Environment Management#

Auto-sync in entrypoint scripts#

...
python manage.py migrate --dry-run

python manage.py syncseeds # <- Add this line

python manage.py runserver

Testing Strategy#

Unit Tests#

Init seed data in tests:

1
2
3
4
5
6
7
8
# conftest.py
import pytest
from django.core.management import call_command
from shop.models import Category, Product
@pytest.fixture(scope='session', autouse=True)
def load_seed_data():
    """Load seed data once per test session."""
    call_command('syncseeds')