Database Setup¶
Configure PostgreSQL for your Aksara application.
Overview¶
Aksara is designed exclusively for PostgreSQL. This design choice enables:
- UUID primary keys with
gen_random_uuid() - JSONB columns for efficient JSON storage
- Advanced indexing including GiST, GIN, and BRIN
- Async performance via the
asyncpgdriver - Reliable transactions with proper ACID compliance
PostgreSQL Installation¶
macOS¶
Download from postgresapp.com and follow the installation wizard.
Linux¶
Windows¶
- Download from postgresql.org
- Run the installer
- Follow the setup wizard
- Remember the password you set for the
postgresuser
Use the Linux instructions inside WSL2 for better compatibility.
Docker¶
The fastest way to get started:
docker run -d \
--name aksara-postgres \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=password \
-e POSTGRES_DB=myapp \
-p 5432:5432 \
-v aksara_pgdata:/var/lib/postgresql/data \
postgres:15
Create a Database¶
Using aksara dbsetup (Recommended)¶
The fastest way to set up your database:
This interactively checks PostgreSQL, prompts for credentials, creates the database, and writes DATABASE_URL to .env. See the Quickstart for the full output.
Using psql¶
# Connect as postgres user
psql -U postgres
# Create a database
CREATE DATABASE myapp;
# Create a user (optional)
CREATE USER myappuser WITH PASSWORD 'secret';
GRANT ALL PRIVILEGES ON DATABASE myapp TO myappuser;
# Exit
\q
Using createdb (Manual Alternative)¶
If you prefer manual database creation instead of aksara dbsetup:
Verify Connection¶
Connection String Format¶
Aksara uses standard PostgreSQL connection strings (also called DSNs):
Examples¶
| Scenario | Connection String |
|---|---|
| Local default | postgresql://localhost/myapp |
| With password | postgresql://postgres:secret@localhost:5432/myapp |
| Remote server | postgresql://user:pass@db.example.com:5432/production |
| Docker | postgresql://postgres:password@localhost:5432/myapp |
| SSL required | postgresql://user:pass@host:5432/db?sslmode=require |
URL Parameters¶
| Parameter | Description | Values |
|---|---|---|
sslmode |
SSL/TLS mode | disable, allow, prefer, require, verify-ca, verify-full |
connect_timeout |
Connection timeout in seconds | Integer |
application_name |
Application name for logging | String |
Example with parameters:
Configure Aksara¶
Using Environment Variables¶
Create a .env file in your project root:
Using configure()¶
from aksara import configure
configure(
database_url="postgresql://postgres:password@localhost:5432/myapp",
pool_min_size=5,
pool_max_size=20,
)
Using Aksara Constructor¶
from aksara import Aksara
app = Aksara(
database_url="postgresql://postgres:password@localhost:5432/myapp",
min_pool_size=5,
max_pool_size=20,
)
Connection Pooling¶
Aksara uses connection pooling via asyncpg for optimal performance.
Pool Settings¶
| Setting | Default | Description |
|---|---|---|
pool_min_size / min_pool_size |
5 | Minimum connections maintained |
pool_max_size / max_pool_size |
20 | Maximum connections allowed |
Recommendations¶
| Workload | Min Size | Max Size |
|---|---|---|
| Development | 2 | 5 |
| Small production | 5 | 20 |
| Medium production | 10 | 50 |
| High traffic | 20 | 100 |
Don't Over-Provision
Each PostgreSQL connection consumes server memory. Set max_size based on your PostgreSQL max_connections setting (typically 100 by default).
Example Configuration¶
import os
from aksara import configure
# Production settings
configure(
database_url=os.environ["DATABASE_URL"],
pool_min_size=10,
pool_max_size=50,
)
Database Lifecycle¶
Aksara automatically manages database connections:
- Startup: Connection pool is created when the app starts
- Request: Connections are borrowed from the pool
- Completion: Connections are returned to the pool
- Shutdown: Pool is closed gracefully
Manual Control (Advanced)¶
from aksara.db import Database
# Get the database instance
db = Database.get_instance()
# Execute raw queries
result = await db.fetch("SELECT * FROM users WHERE email = $1", email)
# Execute single-value queries
count = await db.fetchval("SELECT COUNT(*) FROM users")
# Execute without return
await db.execute("UPDATE users SET active = false WHERE id = $1", user_id)
Multiple Databases¶
For read replicas or multi-tenant setups:
from aksara.db import Database
# Primary database (configured via Aksara)
primary = Database.get_instance()
# Create additional connections
replica = Database(
database_url="postgresql://replica.example.com/myapp",
pool_min_size=2,
pool_max_size=10,
)
await replica.connect()
# Use replica for reads
users = await replica.fetch("SELECT * FROM users")
Database Migrations¶
After configuring your database, create and apply migrations:
# Generate migrations from models
aksara makemigrations --app app.models
# Apply migrations
aksara migrate
# Check migration status
aksara migrate --check
See Migrations for detailed documentation.
Troubleshooting¶
Connection Refused¶
Solutions:
-
Verify PostgreSQL is running:
-
Check the connection string format
-
Ensure the database exists:
Authentication Failed¶
Solutions:
- Verify username and password
- Check
pg_hba.conffor authentication settings - Reset password if needed:
Database Does Not Exist¶
Solution:
SSL Required¶
Solution:
Add ?sslmode=require to your connection string.
Too Many Connections¶
Solutions:
- Reduce
pool_max_size - Increase PostgreSQL
max_connections: - Restart PostgreSQL
Production Recommendations¶
Use Environment Variables¶
Never hardcode credentials:
import os
from aksara import configure
configure(
database_url=os.environ["DATABASE_URL"], # Required in production
)
Enable SSL¶
For remote databases:
Connection Limits¶
Calculate based on your infrastructure:
Health Checks¶
Add a health check endpoint:
from aksara.db import Database
@app.get("/health")
async def health_check():
db = Database.get_instance()
try:
await db.fetchval("SELECT 1")
return {"status": "healthy", "database": "connected"}
except Exception as e:
return {"status": "unhealthy", "database": str(e)}
Related Documentation¶
- Settings — All configuration options
- Migrations — Database schema management
- Running Your App — Development and production