Database Models
Django-CFG provides Pydantic models for type-safe database configuration.
DatabaseConfig
Type-safe database connection configuration with validation.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
engine | str | None | None | Django database engine (auto-detected from URL scheme if not provided) |
name | str | required | Database name or connection string |
user | str | None | None | Database user |
password | str | None | None | Database password (hidden in repr) |
host | str | "localhost" | Database host |
port | int | 5432 | Database port (1-65535) |
connect_timeout | int | 10 | Connection timeout in seconds (≥1) |
sslmode | str | "prefer" | SSL mode for connection |
options | dict[str, Any] | {} | Additional database-specific options |
conn_max_age | int | 0 | Maximum age of database connections in seconds (must be 0 with connection pooling) |
conn_health_checks | bool | True | Enable database connection health checks |
apps | list[str] | [] | Django app labels that should use this database |
operations | list[str] | ["read", "write", "migrate"] | Allowed operations for this database |
migrate_to | str | None | None | Override database alias for migrations |
routing_description | str | "" | Human-readable description of the routing rule |
atomic_requests | bool | None | None | Wrap each HTTP request in a transaction (defaults True for default, False for secondary) |
test_mirror | str | None | None | Mirror this database to another alias during tests |
Methods
| Method | Returns | Description |
|---|---|---|
to_django_config() | dict[str, Any] | Convert to Django database configuration format |
Validation
- Port range: 1-65535
- Timeout: ≥1 second
- Engine: Optional — auto-detected from URL scheme when using
from_url() - Connection string parsing: Supports
postgresql://,mysql://,sqlite:///formats
Usage Examples
SQLite Configuration
from django_cfg import DjangoConfig
from django_cfg.models import DatabaseConfig
class MyConfig(DjangoConfig):
secret_key: str = "your-secret-key"
debug: bool = True
databases: dict = {
'default': DatabaseConfig(
engine='django.db.backends.sqlite3',
name='db/default.sqlite3'
)
}Generated Django settings:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'db/default.sqlite3',
'OPTIONS': {
'connect_timeout': 10,
'sslmode': 'prefer',
}
}
}PostgreSQL Configuration
class MyConfig(DjangoConfig):
secret_key: str = "your-secret-key"
debug: bool = False
databases: dict = {
'default': DatabaseConfig(
engine='django.db.backends.postgresql',
name='production_db',
user='dbuser',
password='secure_password',
host='db.example.com',
port=5432,
sslmode='require',
connect_timeout=30
)
}Generated Django settings:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'production_db',
'USER': 'dbuser',
'PASSWORD': 'secure_password',
'HOST': 'db.example.com',
'PORT': 5432,
'OPTIONS': {
'connect_timeout': 30,
'sslmode': 'require',
}
}
}MySQL Configuration
class MyConfig(DjangoConfig):
secret_key: str = "your-secret-key"
debug: bool = False
databases: dict = {
'default': DatabaseConfig(
engine='django.db.backends.mysql',
name='myapp_db',
user='root',
password='mysql_password',
host='localhost',
port=3306,
options={
'charset': 'utf8mb4',
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"
}
)
}Multi-Database Configuration
class MyConfig(DjangoConfig):
secret_key: str = "your-secret-key"
debug: bool = False
databases: dict = {
'default': DatabaseConfig(
engine='django.db.backends.postgresql',
name='users_db',
user='dbuser',
password='password',
host='localhost'
),
'blog_db': DatabaseConfig(
engine='django.db.backends.postgresql',
name='blog_db',
user='dbuser',
password='password',
host='localhost'
),
'shop_db': DatabaseConfig(
engine='django.db.backends.postgresql',
name='shop_db',
user='dbuser',
password='password',
host='localhost'
)
}DatabaseRoutingRule
Type-safe database routing configuration for multi-database setups.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
apps | list[str] | required | List of Django apps for this rule |
database | str | required | Target database alias |
operations | list[Literal["read", "write", "migrate"]] | ["read", "write", "migrate"] | Allowed operations for this rule |
migrate_to | str | None | None | Override database for migrations |
description | str | "" | Human-readable description of this rule |
Methods
| Method | Returns | Description |
|---|---|---|
matches_app(app_label) | bool | Check if this rule matches the given app |
allows_operation(operation) | bool | Check if this rule allows the given operation |
get_migration_database() | str | Get the database to use for migrations |
Routing Rules Usage
Basic Routing
from django_cfg import DjangoConfig
from django_cfg.models import DatabaseConfig, DatabaseRoutingRule
class MyConfig(DjangoConfig):
secret_key: str = "your-secret-key"
debug: bool = False
databases: dict = {
'default': DatabaseConfig(
engine='django.db.backends.postgresql',
name='users_db',
user='dbuser',
password='password',
host='localhost'
),
'blog_db': DatabaseConfig(
engine='django.db.backends.postgresql',
name='blog_db',
user='dbuser',
password='password',
host='localhost'
)
}
database_routing: list = [
DatabaseRoutingRule(
apps=['blog'],
database='blog_db',
description='Route blog app to blog_db'
)
]Advanced Routing
class MyConfig(DjangoConfig):
secret_key: str = "your-secret-key"
debug: bool = False
databases: dict = {
'default': DatabaseConfig(
engine='django.db.backends.postgresql',
name='users_db',
user='dbuser',
password='password',
host='localhost'
),
'blog_db': DatabaseConfig(
engine='django.db.backends.postgresql',
name='blog_db',
user='dbuser',
password='password',
host='localhost'
),
'shop_db': DatabaseConfig(
engine='django.db.backends.postgresql',
name='shop_db',
user='dbuser',
password='password',
host='localhost'
),
'analytics_db': DatabaseConfig(
engine='django.db.backends.postgresql',
name='analytics_db',
user='readonly',
password='password',
host='analytics-server'
)
}
database_routing: list = [
# Blog app
DatabaseRoutingRule(
apps=['blog'],
database='blog_db',
description='Blog content in blog_db'
),
# Shop app
DatabaseRoutingRule(
apps=['shop', 'payments'],
database='shop_db',
description='E-commerce in shop_db'
),
# Analytics (read-only)
DatabaseRoutingRule(
apps=['analytics'],
database='analytics_db',
operations=['read'], # Read-only
description='Analytics in analytics_db (read-only)'
),
# Separate migrations database
DatabaseRoutingRule(
apps=['legacy'],
database='default',
migrate_to='legacy_migrations_db',
description='Legacy app uses separate migrations DB'
)
]Environment-Specific Configuration
Using Properties
class MyConfig(DjangoConfig):
secret_key: str = "your-secret-key"
@property
def databases(self) -> dict:
if self._environment == "production":
return {
'default': DatabaseConfig(
engine='django.db.backends.postgresql',
name='production_db',
user='prod_user',
password=os.getenv('DB_PASSWORD'),
host='prod-db.example.com',
sslmode='require'
)
}
else:
return {
'default': DatabaseConfig(
engine='django.db.backends.sqlite3',
name='db/dev.sqlite3'
)
}Using YAML
# config.production.yaml
databases:
default:
engine: "django.db.backends.postgresql"
name: "production_db"
user: "prod_user"
password: "${DB_PASSWORD}"
host: "prod-db.example.com"
sslmode: "require"
# config.development.yaml
databases:
default:
engine: "django.db.backends.sqlite3"
name: "db/dev.sqlite3"Connection String Parsing
DatabaseConfig can parse connection URLs:
class MyConfig(DjangoConfig):
secret_key: str = "your-secret-key"
databases: dict = {
'default': DatabaseConfig(
engine='django.db.backends.postgresql',
name='postgresql://user:pass@localhost/dbname'
)
}Supported formats:
- PostgreSQL:
postgresql://user:pass@host:port/dbname - MySQL:
mysql://user:pass@host:port/dbname - SQLite:
sqlite:///path/to/db.sqlite3
Security Best Practices
1. Use Environment Variables
import os
class MyConfig(DjangoConfig):
databases: dict = {
'default': DatabaseConfig(
engine='django.db.backends.postgresql',
name=os.getenv('DB_NAME', 'default_db'),
user=os.getenv('DB_USER', 'dbuser'),
password=os.getenv('DB_PASSWORD'),
host=os.getenv('DB_HOST', 'localhost')
)
}2. Enable SSL in Production
class MyConfig(DjangoConfig):
databases: dict = {
'default': DatabaseConfig(
engine='django.db.backends.postgresql',
name='production_db',
user='prod_user',
password=os.getenv('DB_PASSWORD'),
host='prod-db.example.com',
sslmode='require', # Enforce SSL
options={
'sslrootcert': '/path/to/ca-cert.pem'
}
)
}3. Set Connection Timeouts
class MyConfig(DjangoConfig):
databases: dict = {
'default': DatabaseConfig(
engine='django.db.backends.postgresql',
name='production_db',
user='prod_user',
password=os.getenv('DB_PASSWORD'),
host='prod-db.example.com',
connect_timeout=30, # 30 second timeout
)
}Validation
DatabaseConfig validates:
- Port range (1-65535)
- Timeout (≥1 second)
- Connection string format
- Required fields (
nameonly;engineis optional and auto-detected from URL)
Example validation error:
# ❌ Invalid port
DatabaseConfig(
engine='django.db.backends.postgresql',
name='mydb',
port=99999 # Validation error: port must be ≤ 65535
)See Also
- Database Overview - Database configuration guide
- DjangoConfig - Base configuration class
Last updated on