Flaxon 0.3.0 and Teloce-Py 0.3.0 are available on PyPI. Release instructions are maintained on this site; source links identify the framework snapshot. Check version and upgrade guidance.
Databases
Default project workflow
Generated projects use Flaxon's thin Tortoise ORM integration. Define tables in
root models.py or declare a mounted module's models_module. Configure
DATABASE_URL in settings.py and construct the application with
Flaxon.from_settings(). The connection lifecycle belongs to the application.
from flaxon.db import Model, fields
class Project(Model):
id = fields.IntField(primary_key=True)
name = fields.CharField(max_length=120)
python management.py check
python management.py makemigrations
python management.py migrate --plan
python management.py migrate
python management.py migrate --status
project = await Project.create(name="First project")
projects = await Project.all().order_by("-id")
Read the complete ORM guide before configuring relationships, transactions or Admin. Commit generated Python migrations. Server startup never creates or changes domain tables. JSON migrations belong to the older adapter workflow below; they are not needed by a new ORM project. Existing populated databases require a planned migration transition and backups, rather than replacing their history.
Other database approaches
Overview
Flaxon is database-agnostic.
The default starter uses Tortoise; backend-only applications may choose another database, ORM, or data access pattern. Developers can use any database technology that works with Python.
Supported approaches include:
- SQLAlchemy
- Direct database drivers
- Repository patterns
- PostgreSQL
- SQLite
- MongoDB
- Redis
- Custom database layers
Flaxon is designed to work with both simple applications and large production systems.
Using SQLAlchemy
SQLAlchemy is one of the most popular database tools in Python.
Example with async SQLAlchemy:
from sqlalchemy.ext.asyncio import (
create_async_engine,
AsyncSession
)
from sqlalchemy.orm import sessionmaker
from sqlalchemy import select
DATABASE_URL = (
"postgresql+asyncpg://user:pass@localhost/db"
)
engine = create_async_engine(
DATABASE_URL
)
AsyncSessionLocal = sessionmaker(
engine,
class_=AsyncSession,
expire_on_commit=False
)
@app.on_startup
async def startup():
app.state.db = AsyncSessionLocal
@app.on_shutdown
async def shutdown():
await engine.dispose()
@app.get("/users")
async def get_users():
async with app.state.db() as session:
result = await session.execute(
select(User)
)
users = result.scalars().all()
return [
user.to_dict()
for user in users
]
````
---
# SQLAlchemy with Repository Pattern
The repository pattern separates database logic from application logic.
Example:
```python
from flaxon.database import Repository
from flaxon.database.adapters.sqlalchemy import (
SQLAlchemyAdapter
)
adapter = SQLAlchemyAdapter(
DATABASE_URL
)
db = DatabaseManager(
adapter
)
class UserRepository(Repository):
def __init__(self, db):
super().__init__(
db,
table_name="users"
)
async def find_by_email(
self,
email: str
):
return await self.find_one_by(
"email",
email
)
repo = UserRepository(
db
)
Using asyncpg (PostgreSQL)
For applications that need direct PostgreSQL access:
import asyncpg
@app.on_startup
async def startup():
app.state.db = await asyncpg.create_pool(
host="localhost",
database="mydb",
user="user",
password="password"
)
@app.on_shutdown
async def shutdown():
await app.state.db.close()
@app.get("/users/<int:user_id>")
async def get_user(user_id: int):
row = await app.state.db.fetchrow(
"SELECT * FROM users WHERE id = $1",
user_id
)
return dict(row) if row else None
Using SQLite (aiosqlite)
SQLite is useful for:
- Small applications
- Development environments
- Local tools
Example:
import aiosqlite
@app.on_startup
async def startup():
app.state.db = await aiosqlite.connect(
"app.db"
)
@app.on_shutdown
async def shutdown():
await app.state.db.close()
@app.get("/users")
async def get_users():
cursor = await app.state.db.execute(
"SELECT * FROM users"
)
rows = await cursor.fetchall()
return [
dict(
zip(
["id", "name"],
row
)
)
for row in rows
]
Using MongoDB (Motor)
Flaxon can also work with document databases.
Example:
from motor.motor_asyncio import (
AsyncIOMotorClient
)
@app.on_startup
async def startup():
client = AsyncIOMotorClient(
"mongodb://localhost:27017"
)
app.state.db = client.mydb
@app.get("/users")
async def get_users():
users = await (
app.state.db.users
.find()
.to_list(100)
)
return [
{
"id": str(user["_id"]),
"name": user["name"]
}
for user in users
]
Using Redis
Redis is commonly used for:
- Caching
- Sessions
- Rate limiting
- Queues
Example:
import redis.asyncio as redis
@app.on_startup
async def startup():
app.state.redis = redis.from_url(
"redis://localhost:6379"
)
@app.on_shutdown
async def shutdown():
await app.state.redis.close()
@app.get("/cache/<key>")
async def get_cache(key: str):
value = await app.state.redis.get(
key
)
return {
"key": key,
"value": value
}
Database Health Checks
Flaxon supports database health monitoring.
Example:
from flaxon.health import (
DatabaseHealthCheck
)
db_check = DatabaseHealthCheck(
db
)
health.register(
db_check
)
@app.get("/health/db")
async def db_health():
return await db_check.check()
Transactions
Transactions allow multiple operations to succeed or fail together.
Example:
@app.post("/transfer")
async def transfer(request):
async with app.state.db.transaction() as tx:
await tx.execute(
"""
UPDATE accounts
SET balance = balance - 100
WHERE id = $1
""",
1
)
await tx.execute(
"""
UPDATE accounts
SET balance = balance + 100
WHERE id = $1
""",
2
)
return {
"success": True
}
Migrations
Flaxon supports migration management.
Example:
from flaxon.database import (
MigrationRunner
)
runner = MigrationRunner(
db,
"migrations"
)
version = await runner.generate_migration(
name="create_users_table",
up="""
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL
)
"""
)
await runner.migrate()
await runner.rollback(
steps=1
)
Database Connection Example
Complete database setup:
from flaxon import Flaxon
from flaxon.database import (
DatabaseManager
)
from flaxon.database.adapters.postgresql import (
PostgreSQLAdapter
)
app = Flaxon(
"db-demo"
)
adapter = PostgreSQLAdapter(
host="localhost",
database="mydb",
user="user",
password="pass"
)
db = DatabaseManager(
adapter
)
@app.on_startup
async def startup():
await db.initialize()
@app.on_shutdown
async def shutdown():
await db.close()
@app.get("/users")
async def list_users():
return await db.fetch_all(
"SELECT * FROM users"
)
@app.get("/users/<int:user_id>")
async def get_user(user_id: int):
return await db.fetch_one(
"SELECT * FROM users WHERE id = $1",
user_id
)
@app.post("/users")
async def create_user(request):
data = await request.json()
return await db.fetch_one(
"""
INSERT INTO users (name, email)
VALUES ($1, $2)
RETURNING *
""",
data["name"],
data["email"]
)
Best Practices
For production applications:
- Use connection pooling.
- Keep database credentials in environment variables.
- Use migrations for schema changes.
- Use transactions for multi-step operations.
- Validate user input before database operations.
- Avoid raw SQL when user input is not parameterized.
- Monitor database health.
- Close connections during application shutdown.
Next Steps
Related documentation:
- Authentication
- Security
- Performance
- Configuration
Use this capability in a full-stack app
Flaxon serves Python APIs and Teloce interfaces in one project. Keep validation, authorization and privileged operations on the server; components call those endpoints and present their results. Follow the full-stack lessons and Teloce integration reference to connect this capability to pages, components and application modules.