Repositories
Repositories are the data access layer of Tasteful flavors. They provide an abstraction over data storage and retrieval, isolating business logic from database-specific operations. Repositories handle all interactions with databases, external APIs, and other data sources while providing a clean, testable interface for services.What is a Repository?
A Repository in Tasteful is a class that inherits fromBaseRepository or SQLModelRepository and encapsulates data access logic. Repositories are responsible for:
- Data Access Abstraction: Hiding database-specific implementation details from business logic
- CRUD Operations: Providing Create, Read, Update, and Delete functionality
- Query Management: Handling complex queries and data filtering
- Connection Management: Managing database connections and sessions
- Data Mapping: Converting between database records and domain objects
- Transaction Support: Ensuring data consistency through proper transaction handling
Core Concepts
Repository Hierarchy
Tasteful provides two base repository classes:BaseRepository
The foundational repository class that provides basic structure:SQLModelRepository
The recommended repository class for SQLModel-based applications:Session Management
SQLModelRepository provides robust session management through context managers:
- Automatic Rollback: Sessions automatically rollback on exceptions
- Connection Pooling: Efficient database connection management
- Transaction Safety: Proper transaction boundaries for data consistency
Implementation
Basic Repository Implementation
Here’s a complete example of a repository implementation:Advanced Query Patterns
Repositories can implement complex queries while maintaining clean interfaces:Database Initialization
Repositories can handle database table creation:Integration with Other Components
Service Integration
Repositories are injected into services through dependency injection:Configuration Integration
Repositories receive configuration through dependency injection:Flavor Integration
Repositories are registered in flavor containers:Best Practices
Do’s
- Single Responsibility: Each repository should handle one entity or aggregate
- Interface Consistency: Use consistent method naming across repositories (get_by_id, create, update, delete)
- Session Management: Always use the
get_session()context manager for database operations - Error Handling: Let database exceptions bubble up to services for proper business logic handling
- Query Optimization: Use appropriate indexes and query patterns for performance
- Transaction Boundaries: Keep transactions as short as possible while maintaining consistency
Don’ts
- Business Logic: Don’t put business rules in repositories - they belong in services
- Direct Database Access: Don’t bypass the repository pattern by accessing the database directly from services
- Session Leaks: Don’t store sessions as instance variables - always use context managers
- Complex Joins: Avoid overly complex queries that are hard to maintain - consider breaking them down
- Tight Coupling: Don’t make repositories dependent on other repositories directly