patternpythonModeratepending
Pattern: Database seeding strategy for development and testing
Viewed 0 times
seedingfakerdevelopmentfixturesdeterministictest-data
Problem
Developers need realistic data for local development and testing. Manual data creation is tedious and inconsistent across team members.
Solution
Implement a layered seeding strategy:
# Layer 1: Schema (migrations)
# Handled by migration tool (Prisma, Alembic, etc.)
# Layer 2: Reference data (always needed)
def seed_reference_data(db):
db.insert_many('roles', [
{'id': 'admin', 'name': 'Administrator'},
{'id': 'user', 'name': 'User'},
])
db.insert_many('categories', [...]) # Lookup tables
# Layer 3: Development data (realistic but fake)
def seed_dev_data(db):
from faker import Faker
fake = Faker()
# Create users with deterministic seed for consistency
Faker.seed(42)
users = []
for _ in range(50):
user = db.insert('users', {
'name': fake.name(),
'email': fake.email(),
'created_at': fake.date_time_this_year(),
})
users.append(user)
# Create related data
for user in users:
for _ in range(random.randint(0, 5)):
db.insert('orders', {
'user_id': user['id'],
'total': round(random.uniform(10, 500), 2),
})
# Layer 4: Test fixtures (specific scenarios)
def seed_test_fixtures(db):
# Known data for specific test cases
db.insert('users', {'id': 'test-user-1', 'name': 'Test User', ...})
# Commands:
# make seed -> reference + dev data
# make seed-test -> reference + test fixtures
# make seed-fresh -> drop all, remigrate, reseed
# Layer 1: Schema (migrations)
# Handled by migration tool (Prisma, Alembic, etc.)
# Layer 2: Reference data (always needed)
def seed_reference_data(db):
db.insert_many('roles', [
{'id': 'admin', 'name': 'Administrator'},
{'id': 'user', 'name': 'User'},
])
db.insert_many('categories', [...]) # Lookup tables
# Layer 3: Development data (realistic but fake)
def seed_dev_data(db):
from faker import Faker
fake = Faker()
# Create users with deterministic seed for consistency
Faker.seed(42)
users = []
for _ in range(50):
user = db.insert('users', {
'name': fake.name(),
'email': fake.email(),
'created_at': fake.date_time_this_year(),
})
users.append(user)
# Create related data
for user in users:
for _ in range(random.randint(0, 5)):
db.insert('orders', {
'user_id': user['id'],
'total': round(random.uniform(10, 500), 2),
})
# Layer 4: Test fixtures (specific scenarios)
def seed_test_fixtures(db):
# Known data for specific test cases
db.insert('users', {'id': 'test-user-1', 'name': 'Test User', ...})
# Commands:
# make seed -> reference + dev data
# make seed-test -> reference + test fixtures
# make seed-fresh -> drop all, remigrate, reseed
Why
Deterministic seeding (fixed random seed) ensures all developers see the same data, making bug reports reproducible.
Revisions (0)
No revisions yet.