Database & ORM
Framefox provides a sophisticated ORM (Object-Relational Mapping) system built on top of SQLModel and SQLAlchemy 2.0. The framework integrates a powerful QueryBuilder, advanced Entity Manager with identity mapping, and a comprehensive driver system supporting multiple database engines.
The ORM architecture emphasizes developer productivity through fluent query interfaces, automatic change tracking, and seamless database abstraction. Whether youβre building a simple application with SQLite or a complex enterprise system with PostgreSQL, Framefox adapts to your needs without code modifications.
Database Drivers & Connection Management
Section titled βDatabase Drivers & Connection ManagementβFramefox uses a sophisticated connection management system through the ConnectionManager
class that handles database driver initialization, connection pooling, and lifecycle management.
Database Configuration
Section titled βDatabase ConfigurationβFramefox supports multiple database engines through a flexible configuration system. When you initialize a new project with framefox init
, the framework automatically generates the necessary configuration files for database setup.
Environment Variables (Production Priority)
Section titled βEnvironment Variables (Production Priority)βThe primary configuration method uses environment variables in the .env
file, which is ideal for production environments where credentials are stored as secrets:
# .env (generated by framefox init)#==============================# Database#==============================
# SQLite (default for development)DATABASE_URL=sqlite:///app.db
# PostgreSQL (recommended for production)# DATABASE_URL=postgresql://root:password@localhost:5432/dbname
# MySQL/MariaDB# DATABASE_URL=mysql://root:password@localhost:3306/dbname
This approach prioritizes security by keeping sensitive database credentials out of your codebase and version control.
Supported Database Drivers
Section titled βSupported Database DriversβDriver: Built-in Python support (no additional installation required)
- Development: Perfect for local development and testing
- Production: Suitable for small to medium applications
- Features: Zero-configuration, file-based, ACID compliant
- Limitations: No concurrent writes, limited scalability
DATABASE_URL=sqlite:///app.db
# Absolute pathDATABASE_URL=sqlite:///var/data/myapp.db
# In-memory (testing only)DATABASE_URL=sqlite:///:memory:
PostgreSQL
Section titled βPostgreSQLβDriver: psycopg2
or asyncpg
(for async operations)
- Installation:
pip install psycopg2-binary
orpip install asyncpg
- Production: Excellent for high-performance applications
- Features: Full ACID compliance, advanced indexing, JSON support
DATABASE_URL=postgresql://username:password@localhost:5432/database_name
# With SSL (production)DATABASE_URL=postgresql://username:password@host:5432/db?sslmode=require
# Cloud providers (example)DATABASE_URL=postgresql://user:pass@cloud-host:5432/db?sslmode=require
MySQL/MariaDB
Section titled βMySQL/MariaDBβDriver: mysqlclient
or PyMySQL
- Installation:
pip install mysqlclient
orpip install PyMySQL
- Production: Solid choice for web applications
- Features: High performance, replication support, wide hosting support
DATABASE_URL=mysql://username:password@localhost:3306/database_name
# With PyMySQL driver (more compatible)DATABASE_URL=mysql+pymysql://username:password@localhost:3306/database_name
# With SSL and charsetDATABASE_URL=mysql://user:pass@host:3306/db?charset=utf8mb4&ssl_ca=/path/to/ca.pem
Advanced Configuration with orm.yaml
Section titled βAdvanced Configuration with orm.yamlβFor more advanced database settings, Framefox provides the config/orm.yaml
file with detailed connection parameters:
# config/orm.yaml (generated by framefox init)database: # Primary configuration - uses environment variable url: "${DATABASE_URL}"
# Detailed configuration (used when DATABASE_URL is not available) # Useful for Docker/Kubernetes environments or complex setups # driver: "${DATABASE_DRIVER:-postgresql}" # host: "${DATABASE_HOST:-localhost}" # port: "${DATABASE_PORT:-5432}" # username: "${DATABASE_USER:-framefox}" # password: "${DATABASE_PASSWORD}" # database: "${DATABASE_NAME:-framefoxdb}" # charset: "utf8mb4"
# Connection pooling settings (important for production) pool_size: 20 max_overflow: 10 pool_timeout: 30 pool_recycle: 1800 pool_pre_ping: true autocommit: false autoflush: false
logging: echo_sql: false # Set to true for SQL debugging
Configuration Priority
Section titled βConfiguration PriorityβFramefox follows this configuration priority order:
DATABASE_URL
environment variable (highest priority)url
field in orm.yaml- Detailed configuration fields in orm.yaml (fallback)
When to Use Detailed Configuration
Section titled βWhen to Use Detailed ConfigurationβThe commented detailed configuration is useful when:
- Container environments where individual environment variables are easier to manage
- Service discovery where host/port are dynamically assigned
- Complex authentication requiring separate credential management
- Multi-database setups where URL construction is complex
Example for containerized environments:
database: # Comment out the url line to use detailed config # url: "${DATABASE_URL}"
# Uncomment and use environment variables driver: "${DATABASE_DRIVER:-postgresql}" host: "${DATABASE_HOST:-db-service}" port: "${DATABASE_PORT:-5432}" username: "${DATABASE_USER}" password: "${DATABASE_PASSWORD}" database: "${DATABASE_NAME}"
Connection Pool Configuration
Section titled βConnection Pool ConfigurationβThe connection pool settings in orm.yaml
control database performance:
pool_size
: Number of persistent connections to maintainmax_overflow
: Additional connections beyond pool_size when neededpool_timeout
: Seconds to wait for an available connectionpool_recycle
: Seconds before recreating connections (prevents timeout)pool_pre_ping
: Test connections before use (prevents stale connections)
Creating the Database
Section titled βCreating the DatabaseβOnce your database configuration is set, create the database using the CLI command:
framefox database create
This command:
- Reads your database configuration from
.env
andorm.yaml
- Creates the database if it doesnβt exist (for PostgreSQL/MySQL)
- Verifies the connection and reports success or failure
- Sets up the Alembic version table for migration tracking
Output examples:
# SuccessDatabase 'myapp_db' created successfully
# Already existsThe database 'myapp_db' already exists
# ErrorError while creating the database: connection refused
Dropping the Database
Section titled βDropping the DatabaseβTo completely remove a database and all its data, use the drop command:
framefox database drop
This command:
- Displays database information (type and name) before deletion
- Requires confirmation to prevent accidental data loss
- Checks database existence and warns if already absent
- Completely removes the database and all its tables/data
Example interaction:
Database type: postgresqlDatabase name: myapp_db
β οΈ WARNING: You are about to drop the database. All data will be lost.Do you want to continue? [y/N]: yDatabase dropped successfully: myapp_db
Data Loss Warning
The drop
command permanently deletes:
- All database tables and their data
- All migration history and schema information
- All indexes, constraints, and triggers
- The database itself (PostgreSQL/MySQL)
For SQLite, the entire database file is deleted. This operation cannot be undone.
Entities
Section titled βEntitiesβWhat is an Entity?
Section titled βWhat is an Entity?βAn entity represents a data model in your application - a Python class that maps directly to a database table. In the MVC (Model-View-Controller) architectural pattern, entities serve as the Model layer, encapsulating the structure, validation rules, and relationships of your data.
Think of an entity as a blueprint for your data. When you create a User
entity, youβre defining what a user looks like in your database - it has a username, email, password, and relationships to other entities like games or profiles.
Framefox entities are SQLModel classes that represent database tables. They combine SQLAlchemyβs ORM capabilities with Pydanticβs validation and serialization features.
Defining Entities
Section titled βDefining EntitiesβIn Framefox, entities must inherit from AbstractEntity
which provides essential framework features:
from sqlmodel import Field, Relationshipfrom framefox.core.orm.abstract_entity import AbstractEntity
class User(AbstractEntity, table=True): id: int | None = Field(default=None, primary_key=True) username: str = Field(max_length=50, unique=True) email: str = Field(max_length=255, unique=True)
# Relationships games: list["Game"] = Relationship(back_populates="user")
class Game(AbstractEntity, table=True): id: int | None = Field(default=None, primary_key=True) title: str = Field(max_length=100) user_id: int | None = Field(foreign_key="user.id", nullable=False)
# Relationships user: User | None = Relationship(back_populates="games")
Entity Features
Section titled βEntity Featuresβ- Type Safety: Full Python type hints with Pydantic validation
- Relationships: Foreign keys and navigation properties
- Validation: Automatic data validation on creation and updates
- Serialization: JSON serialization for API responses
- Metadata: Table names, indexes, and constraints
Creating Entities with CLI
Section titled βCreating Entities with CLIβFramefox provides a command-line tool to generate entities interactively:
framefox create entity
This command:
- Prompts for entity name as the first question
- Creates the entity file in
src/entity/{name}.py
- Interactive prompts for adding properties (name, type, constraints)
- Generates relationships with other entities
- Handles foreign keys and bidirectional relations automatically
- Uses modern type syntax with
| None
for optional fields
Example interaction:
What is the entity name? userProperty name: usernameProperty type: strMax length (optional): 50Unique constraint? (y/N): y
Property name: emailProperty type: strMax length (optional): 255Unique constraint? (y/N): y
Property name: (press enter to finish)Entity 'User' created successfully at src/entity/user.py
Generated code:
from sqlmodel import Fieldfrom framefox.core.orm.abstract_entity import AbstractEntity
class User(AbstractEntity, table=True): id: int | None = Field(default=None, primary_key=True) username: str = Field(max_length=50, unique=True) email: str = Field(max_length=255, unique=True)
When you create an entity using the CLI, Framefox automatically generates a corresponding repository in src/repository/
. For example, creating a Game
entity generates src/repository/game_repository.py
:
from framefox.core.orm.abstract_repository import AbstractRepositoryfrom src.entity.game import Game
""" Available Methods:find(id) # Retrieve entity by IDfind_all() # Retrieve all entitiesfind_by(criteria, order_by=None, limit=None, offset=None) # Retrieve entities by criteriaget_query_builder() # Get QueryBuilder instance for complex queries
Example:game = game_repo.find(1)games = game_repo.find_all()user_games = game_repo.find_by({"user_id": 1})"""
class GameRepository(AbstractRepository): def __init__(self): super().__init__(Game)
########### # Build your own queries using the QueryBuilder ########### # def get_games_by_user(self, user_id: int): # query_builder = self.get_query_builder() # return ( # query_builder # .select() # .where(self.model.user_id == user_id) # .all() # )
Direct Table Creation from Entities
Section titled βDirect Table Creation from EntitiesβFor rapid prototyping or when you need to create database tables directly from your entity definitions without using migrations, Framefox provides the copy command:
framefox database copy
This command:
- Scans the
src/entity/
directory for SQLModel entity classes - Creates database tables directly from entity definitions
- Skips the migration system for direct table creation
- Requires database to exist first (use
framefox database create
) - Useful for development and prototyping scenarios
Example workflow:
# First, ensure your database existsframefox database create
# Then copy your entity definitions to database tablesframefox database copy
Output:
Scanning entities in src/entity/...Found SQLModel classes: User, Game, ProfileCreating tables from entity definitions...Tables created successfully.
You should try framefox create crud
The copy command is particularly useful during early development when youβre still iterating on your entity designs and donβt need the overhead of migration management.
Repositories
Section titled βRepositoriesβFramefox repositories provide a clean abstraction layer over database operations. All repositories inherit from AbstractRepository
, which provides core database operations and QueryBuilder integration.
As shown in the entity creation section above, repositories are automatically generated when you create entities using the CLI. The generated repository follows the correct Framefox pattern.
Repository Structure
Section titled βRepository StructureβEvery repository inherits from AbstractRepository
and follows this pattern:
from framefox.core.orm.abstract_repository import AbstractRepositoryfrom src.entity.user import User
class UserRepository(AbstractRepository): def __init__(self): super().__init__(User) # Pass the entity class to the parent constructor
# Custom repository methods def find_active_users(self) -> list[User]: return self.find_by({"is_active": True})
def find_by_email(self, email: str) -> User | None: return self.find_one_by({"email": email})
Built-in Repository Methods
Section titled βBuilt-in Repository MethodsβEvery repository automatically provides these methods:
# Basic CRUD operationsuser = user_repo.find(1) # Find by IDusers = user_repo.find_all() # Get all entitiesactive_users = user_repo.find_by({"is_active": True}) # Find with criteriauser = user_repo.find_one_by({"email": "test@example.com"}) # Find single entity
# Advanced queriesquery_builder = user_repo.get_query_builder() # Get QueryBuilder for complex queries
Repository Registration
Section titled βRepository RegistrationβRepositories are automatically registered through the dependency injection system when the application starts. Simply create your repository class and it becomes available for injection in controllers and services.
Entity Manager
Section titled βEntity ManagerβThe EntityManager is the central coordinator for all database operations and entity lifecycle management in Framefoxβs ORM architecture. Acting as an implementation of the Unit of Work pattern, it tracks changes to entities throughout their lifecycle and ensures that database operations are executed efficiently and safely within transactional boundaries.
Understanding the EntityManager
Section titled βUnderstanding the EntityManagerβThe EntityManager operates on the principle of dirty checking - it knows exactly which properties of which entities have been modified since they were loaded from the database. This allows it to generate optimal UPDATE statements that only modify the changed fields, rather than updating entire records unnecessarily.
Think of the EntityManager as your applicationβs database session manager and transaction coordinator. It maintains an internal state of all entities youβre working with, tracks their changes, and provides intelligent batching of database operations. When you retrieve an entity from the database, modify it, and then commit your changes, the EntityManager handles all the complex SQL generation, change detection, and database synchronization behind the scenes.
Core Features
Section titled βCore FeaturesβThe EntityManager provides several key capabilities:
- Identity Map: Ensures each entity is only loaded once per session, preventing duplicate objects
- Change Tracking: Automatically detects modifications to entities using dirty checking
- Transaction Management: Handles database transactions with automatic rollback on exceptions
- Request-Scoped Lifecycle: Each HTTP request gets its own EntityManager instance
- Session Management: Manages SQLAlchemy sessions with proper cleanup
- Repository Integration: Works seamlessly with repository pattern
EntityManagerInterface vs EntityManager
Section titled βEntityManagerInterface vs EntityManagerβFramefox provides two ways to work with the EntityManager:
EntityManagerInterface (Recommended)
Section titled βEntityManagerInterface (Recommended)βThe EntityManagerInterface is the recommended approach for most use cases:
from framefox.core.orm.entity_manager_interface import EntityManagerInterface
class UserService: def __init__(self, entity_manager: EntityManagerInterface): self.em = entity_manager # Interface - can be injected in constructor
def create_user(self, user_data: dict) -> User: user = User(**user_data) self.em.persist(user) self.em.commit() return user
Benefits of EntityManagerInterface:
- Constructor injection supported: Can be injected in controller/service constructors
- Context-aware: Automatically resolves to the correct EntityManager instance
- Request lifecycle managed: Handles request-scoped EntityManager lifecycle
- Testing friendly: Easy to mock and test
- Thread-safe: Ensures proper isolation between execution contexts
Direct EntityManager (Method Injection Only)
Section titled βDirect EntityManager (Method Injection Only)βThe concrete EntityManager class can only be used via method-level autowiring:
from framefox.core.orm.entity_manager import EntityManagerfrom framefox.core.routing.decorator.route import Route
class UserController: # β INCORRECT: Cannot inject EntityManager in constructor # def __init__(self, entity_manager: EntityManager): # self.entity_manager = entity_manager
@Route("/users", "create_user", ["POST"]) async def create_user(self, user_data: dict, entity_manager: EntityManager): # β
CORRECT: EntityManager autowired in method parameters user = User(**user_data) entity_manager.persist(user) entity_manager.commit() return user
Why method injection only?
- Request-scoped lifecycle: EntityManager instances are tied to specific HTTP requests
- Middleware dependency: Created and managed by EntityManagerMiddleware
- Session isolation: Each request needs its own isolated database session
Entity Manager Operations
Section titled βEntity Manager OperationsβBasic CRUD Operations
Section titled βBasic CRUD Operationsβ# Create and persist entitiesuser = User(username="john", email="john@example.com")entity_manager.persist(user)entity_manager.commit()
# Find entities by primary keyuser = entity_manager.find(User, 1)user = entity_manager.find(User, {"id": 1}) # Alternative syntax
# Check if entity exists in databaseexisting_user = entity_manager.find_existing_entity(user)
# Delete entitiesentity_manager.delete(user)entity_manager.commit()
# Refresh entity from databaseentity_manager.refresh(user) # Reloads from DB, discarding local changes
Transaction Management
Section titled βTransaction Managementβ# Explicit transaction controltry: with entity_manager.transaction(): user = User(username="john") entity_manager.persist(user)
game = Game(title="My Game", user_id=user.id) entity_manager.persist(game)
# Transaction auto-commits on successful completion # Auto-rollback on exceptionexcept Exception as e: # Transaction already rolled back print(f"Transaction failed: {e}")
# Manual transaction controlentity_manager.persist(user)entity_manager.commit() # Manual commit
# Or rollback if neededentity_manager.rollback()
Advanced Operations
Section titled βAdvanced Operationsβ# Execute raw SQL statementsfrom sqlmodel import textresults = entity_manager.exec_statement( text("SELECT * FROM users WHERE active = :active") .params(active=True))
# Get repository for entityuser_repo = entity_manager.get_repository(User)active_users = user_repo.find_by({"is_active": True})
# Session access for complex operationssession = entity_manager.sessioncomplex_query = session.query(User).join(Game).filter(...)
Identity Map and Change Tracking
Section titled βIdentity Map and Change TrackingβThe EntityManager maintains an identity map that ensures each database record is represented by exactly one object instance within a session:
# Both calls return the same object instanceuser1 = entity_manager.find(User, 1)user2 = entity_manager.find(User, 1)assert user1 is user2 # True - same object reference
# Changes are automatically trackeduser1.username = "new_username"entity_manager.commit() # UPDATE users SET username='new_username' WHERE id=1
# No explicit save() needed - changes detected automatically
Dependency Injection Patterns
Section titled βDependency Injection PatternsβService Layer with EntityManagerInterface
Section titled βService Layer with EntityManagerInterfaceβfrom framefox.core.orm.entity_manager_interface import EntityManagerInterface
class GameService: def __init__(self, entity_manager: EntityManagerInterface): self.em = entity_manager
def create_game_for_user(self, game_data: dict, user_id: int) -> Game: try: with self.em.transaction(): # Create game game = Game(**game_data) game.user_id = user_id self.em.persist(game)
return game except Exception as e: # Transaction automatically rolled back raise RuntimeError(f"Failed to create game: {str(e)}")
Controller with Method Injection
Section titled βController with Method Injectionβfrom framefox.core.routing.decorator.route import Routefrom framefox.core.orm.entity_manager import EntityManager
class GameController: @Route("/games/{game_id}", "update_game", ["PUT"]) async def update_game(self, game_id: int, game_data: dict, entity_manager: EntityManager): game = entity_manager.find(Game, game_id) if not game: raise HTTPException(404, "Game not found")
# Update game properties for field, value in game_data.items(): if hasattr(game, field): setattr(game, field, value)
# Changes automatically detected and committed by middleware return game
Injection Limitations
EntityManager (concrete class):
- β Cannot be injected in constructor (
__init__
) - β Can be autowired in controller method parameters
- β Managed by request lifecycle middleware
EntityManagerInterface:
- β
Can be injected in constructor (
__init__
) - β Can be autowired in controller method parameters
- β Provides context-aware EntityManager resolution
Best Practices
Section titled βBest PracticesβDatabase Migrations: Schema Evolution
Section titled βDatabase Migrations: Schema EvolutionβDatabase migrations provide version control for your database schema, allowing you to evolve your database structure systematically over time. Framefox uses Alembic, the migration tool built by the SQLAlchemy team, to handle all schema changes automatically.
Migration Workflow
Section titled βMigration WorkflowβFramefox follows a streamlined migration workflow:
- Modify Entities: Make changes to your entity classes
- Generate Migration: Create migration files automatically
- Review Migration: Examine the generated migration file for accuracy
- Apply Migration: Update the database schema
- Version Control: Commit migration files to your repository
Creating Migrations
Section titled βCreating MigrationsβGenerate a new migration file based on entity changes:
framefox database create-migration
This command:
- Compares current entities with the existing database schema
- Auto-generates migration code with timestamp-based filename
- Creates
migrations/versions/
directory if it doesnβt exist - Detects schema changes (tables, columns, indexes, constraints)
- Removes empty migrations if no changes are detected
Output examples:
# Changes detectedMigration created: migrations/versions/20240620_143025_migration.pyMigration file generated successfully
# No changesNo changes detected since the last migration.
# Database doesn't existThe database does not exist. Please run 'framefox database create' first.
Generated migration file:
"""Migration
Revision ID: 20240620_143025Revises:Create Date: 2024-06-20 14:30:25.000000"""from alembic import opimport sqlalchemy as sa
def upgrade(): """Add new columns and constraints""" op.add_column('users', sa.Column('avatar_url', sa.String(255), nullable=True)) op.create_index('ix_users_avatar_url', 'users', ['avatar_url'])
def downgrade(): """Remove added columns and constraints""" op.drop_index('ix_users_avatar_url', table_name='users') op.drop_column('users', 'avatar_url')
Applying Migrations
Section titled βApplying MigrationsβApply pending migrations to update the database schema:
framefox database upgrade
This command:
- Checks database existence and creates it if necessary
- Applies all pending migrations in chronological order
- Updates the
alembic_version
table with current migration state - Handles migration dependencies automatically
- Reports success or failure with detailed information
Output examples:
# SuccessRunning upgrade -> ae1027a6acf, add user avatar columnMigration completed successfullyCurrent revision: ae1027a6acf
# Already up to dateDatabase is already up to date
# ErrorError during upgrade: column "avatar_url" already exists
Checking Migration Status
Section titled βChecking Migration StatusβView the current migration status and history:
framefox database status
This command provides:
- Database connection status and configuration details
- Current migration revision and timestamp
- List of all migrations with applied/pending status
- Migration file details and descriptions
Output example:
Database Status
Database Configuration: URL: sqlite:///app.db Status: Connected β Current Revision: ae1027a6acf (head)
Migration History:ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Revision β Status β Description β Date ββ‘ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ©β ae1027a6acf β APPLIED β add user avatar column β 2024-06-20 14:30 ββ d4e5f6a7b8c9 β APPLIED β create initial tables β 2024-06-18 09:15 ββ base β APPLIED β initial migration β 2024-06-18 09:00 βββββββββββββββββββ΄βββββββββββ΄βββββββββββββββββββββββββββββββ΄βββββββββββββββββββββ
Downgrading Migrations
Section titled βDowngrading MigrationsβRevert to a previous migration version:
# Downgrade one stepframefox database downgrade
# Downgrade to specific revisionframefox database downgrade --revision d4e5f6a7b8c9
# Downgrade to base (remove all migrations)framefox database downgrade --revision base
This command:
- Reverts schema changes in reverse chronological order
- Executes downgrade functions from migration files
- Updates migration tracking to the target revision
- Preserves data when possible (depends on migration design)
Database Schema Diagram
Section titled βDatabase Schema DiagramβGenerate a visual representation of your database schema:
framefox database diagram
This command:
- Analyzes current database schema including tables, columns, and relationships
- Generates Mermaid diagram code for visualization
- Creates diagram files in multiple formats (
.md
,.mmd
) - Includes entity relationships and foreign key constraints
- Saves output to
docs/database_schema.md
by default
Output example:
Database diagram generated successfullyOutput files: - docs/database_schema.md (Markdown with Mermaid) - docs/database_schema.mmd (Mermaid source)
Entities included: User, Game, ProfileRelationships mapped: 3
Database Maintenance & Troubleshooting
Section titled βDatabase Maintenance & TroubleshootingβFramefox provides several maintenance commands to help resolve database and migration issues during development.
Clearing Migration History
Section titled βClearing Migration HistoryβWhen you need to reset your migration history and start fresh:
framefox database clear-migration
This command:
- Removes all migration files from the
migrations/versions/
directory - Clears the alembic_version table in the database
- Preserves essential files like
env.py
andscript.py.mako
- Recreates directory structure for new migrations
- Checks database existence before attempting to clear the version table
Example output:
Clearing migration files and database references...Migration table clearedMigration files clearedMigration files and database references cleared successfullyYou can now create new migrations with 'framefox database create-migration'
Use cases:
- Development reset: When prototyping and need to start migration history over
- Problematic migrations: When migration conflicts or corruption occur
- Major refactoring: When entity structure changes significantly
- Team synchronization: When merging conflicting migration branches
Development Only
The clear-migration
command should only be used in development environments. In production:
- Migration history is crucial for database integrity
- Use proper rollback strategies instead
- Coordinate with your team before clearing migrations
Clearing SQLAlchemy Metadata
Section titled βClearing SQLAlchemy MetadataβWhen you encounter mapper or metadata conflicts:
framefox database clear-metadata
This command:
- Clears SQLAlchemy registry and removes stale mappers
- Resets SQLModel metadata to prevent conflicts
- Resolves entity mapping issues caused by code changes
- Clears Python module cache for clean reloading
- Requires application restart to take effect
Example output:
Cleaning SQLAlchemy metadata...SQLModel.metadata cleanedSQLModel registry cleanedMetadata cleaned successfullyRestart your application to apply the changes
Common scenarios:
- Entity class modifications: After changing entity definitions
- Import conflicts: When entity imports cause circular dependencies
- Mapper errors: When SQLAlchemy complains about duplicate mappings
- Development environment: After major code restructuring
Complete Migration Reset
Section titled βComplete Migration ResetβFor comprehensive troubleshooting during development:
# Clear all migrations and metadataframefox database clear-migrationframefox database clear-metadata
# Recreate database schema from current entitiesframefox database copy
# Or create a fresh migrationframefox database create-migration "initial_schema"
Related Topics
Section titled βRelated Topicsβπ§ Advanced Configuration: Production Database Setup - How to configure connection pooling and SSL for production?
π Advanced Relationships: Complex Entity Patterns - Need help with polymorphic associations and inheritance?
π Query Builder: Advanced Queries & Repository Patterns - Want to master complex queries and performance optimization?
β‘ Entity Manager: Transactions & Performance - Ready to explore transaction management and batch operations?
π¦ Migration Management: Schema Evolution Strategies - Looking for advanced migration techniques and deployment strategies?