Skip to main content
This guide outlines the process for adding new database models to the Definable backend codebase.

Overview

Models in our application represent database tables and provide a foundation for data storage and retrieval. All models use SQLAlchemy ORM and follow a consistent pattern to ensure compatibility with our CRUD operations.

Step 1: Create the Model File

Create a new Python file in the src/models directory with a descriptive name that follows the naming convention of existing model files (e.g., my_feature_model.py).

Step 2: Import and Register the Model

Update the src/models/__init__.py file to import and expose your new model:

Step 3: Create a Migration

Migrations are necessary to update the database schema with your new model. We use Alembic for database migrations.
  1. Generate a new migration:
  1. Review the generated migration file in the migrations/versions directory to ensure it correctly creates the intended table and relationships.
  2. Apply the migration:

Step 4: Define Schema Validation Classes

Create schema validation classes for your model in the appropriate service directory (e.g., src/services/my_feature/schema.py). These classes will be used for request validation and serialization.

Model Design Best Practices

  1. Inheritance: Use CRUD for models that need standard CRUD operations, and Base for association tables or models with specialized operations.
  2. Field Types:
    • Use String(255) for short text fields
    • Use Text for longer text content
    • Use JSONB for structured data/configurations
    • Use UUID for all IDs and foreign keys
  3. Relationships:
    • Always define ForeignKey constraints with appropriate ondelete behavior
    • Use CASCADE for parent-child relationships where child records should be deleted when parent is deleted
    • Use SET NULL where records should be preserved but reference removed
  4. Default Values:
    • Always provide both Python defaults and database server defaults for boolean fields
    • Use nullable=False for required fields
  5. Documentation:
    • Add docstrings to all model classes
    • Document any non-obvious field usage

Example Models

Simple Model Example (agent_model.py)

Association Table Example (agent_model.py)

Testing Models

After creating your model, you should thoroughly test its functionality:
  1. Unit Tests:
    • Test model instantiation
    • Test constraints and validations
    • Test relationship behavior
  2. Integration Tests:
    • Test database operations (create, read, update, delete)
    • Test model interactions with related models

Troubleshooting

Common Issues

  1. Migration errors:
    • Check for incorrect field types
    • Verify foreign key relationships point to valid tables
    • Ensure the migration runs in the correct sequence
  2. Validation errors:
    • Ensure Pydantic schemas correctly reflect model fields
    • Check for appropriate validators and field constraints
  3. Runtime errors:
    • Check for missing nullable constraints
    • Verify default values are correctly set

Getting Help

If you encounter issues with model creation or migration, consult:
  • The SQLAlchemy documentation
  • The Alembic migration documentation
  • Reach out to the development team for assistance