Flask Integration¶
Advanced Alchemy integrates with Flask through an extension that manages application-context sessions, supports sync and async SQLAlchemy configs, and registers database migration commands on the Flask CLI.
Basic Setup¶
Use SQLAlchemySyncConfig for standard Flask applications:
from flask import Flask
from sqlalchemy import select
from sqlalchemy.orm import Mapped
from advanced_alchemy.extensions.flask import AdvancedAlchemy, SQLAlchemySyncConfig, base
class User(base.BigIntBase):
__tablename__ = "flask_user_account"
name: Mapped[str]
app = Flask(__name__)
alchemy = AdvancedAlchemy(
SQLAlchemySyncConfig(
connection_string="sqlite:///local.db",
commit_mode="autocommit",
create_all=True,
),
app,
)
@app.route("/users")
def list_users() -> dict[str, list[dict[str, object]]]:
session = alchemy.get_sync_session()
users = session.execute(select(User)).scalars().all()
return {"users": [{"id": user.id, "name": user.name} for user in users]}
Sessions are cached on Flask’s application context, so repeated get_session() calls within the same request
reuse the same SQLAlchemy session.
Multiple Databases¶
Provide a sequence of configs when you need more than one bind key:
configs = [
SQLAlchemySyncConfig(connection_string="sqlite:///users.db", bind_key="users"),
SQLAlchemySyncConfig(connection_string="sqlite:///products.db", bind_key="products"),
]
alchemy = AdvancedAlchemy(configs, app)
users_session = alchemy.get_sync_session("users")
products_session = alchemy.get_sync_session("products")
If you register multiple configs, call get_session() or get_sync_session() with an explicit bind key unless
you also have a default bind configured.
Async Support¶
Flask can also work with async SQLAlchemy sessions:
from advanced_alchemy.extensions.flask import SQLAlchemyAsyncConfig
alchemy = AdvancedAlchemy(
SQLAlchemyAsyncConfig(
connection_string="sqlite+aiosqlite:///local.db",
create_all=True,
),
app,
)
@app.route("/users")
async def list_users_async() -> dict[str, list[dict[str, object]]]:
session = alchemy.get_async_session()
users = (await session.execute(select(User))).scalars().all()
return {"users": [{"id": user.id, "name": user.name} for user in users]}
For sync routes that need to call an async session explicitly, use the extension portal:
@app.route("/users/sync-bridge")
def list_users_via_portal() -> dict[str, list[dict[str, object]]]:
session = alchemy.get_async_session()
users = alchemy.portal.call(session.execute, select(User)).scalars().all()
return {"users": [{"id": user.id, "name": user.name} for user in users]}
Service Integration¶
FlaskServiceMixin adds a jsonify() helper that serializes service results using Advanced Alchemy’s configured serializer:
import datetime
from typing import Optional
from uuid import UUID
from flask import request
from msgspec import Struct
from sqlalchemy.orm import Mapped
from advanced_alchemy.extensions.flask import (
FlaskServiceMixin,
SQLAlchemySyncConfig,
AdvancedAlchemy,
base,
filters,
repository,
service,
)
class Author(base.UUIDBase):
__tablename__ = "flask_author"
name: Mapped[str]
dob: Mapped[Optional[datetime.date]]
class AuthorSchema(Struct):
id: Optional[UUID] = None
name: str
dob: Optional[datetime.date] = None
class AuthorService(service.SQLAlchemySyncRepositoryService[Author], FlaskServiceMixin):
class Repo(repository.SQLAlchemySyncRepository[Author]):
model_type = Author
repository_type = Repo
alchemy = AdvancedAlchemy(
SQLAlchemySyncConfig(connection_string="sqlite:///local.db", commit_mode="autocommit"),
app,
)
@app.route("/authors", methods=["GET"])
def list_authors():
current_page = request.args.get("currentPage", 1, type=int)
page_size = request.args.get("pageSize", 10, type=int)
limit_offset = filters.LimitOffset(limit=page_size, offset=page_size * (current_page - 1))
author_service = AuthorService(session=alchemy.get_sync_session())
results, total = author_service.get_many_and_count(limit_offset)
payload = author_service.to_schema(
results,
total,
filters=[limit_offset],
schema_type=AuthorSchema,
)
return author_service.jsonify(payload)
@app.route("/authors", methods=["POST"])
def create_author():
author_service = AuthorService(session=alchemy.get_sync_session())
author = author_service.create(data=request.get_json())
return author_service.jsonify(author_service.to_schema(author, schema_type=AuthorSchema))
import datetime
from uuid import UUID
from flask import request
from msgspec import Struct
from sqlalchemy.orm import Mapped
from advanced_alchemy.extensions.flask import (
FlaskServiceMixin,
SQLAlchemySyncConfig,
AdvancedAlchemy,
base,
filters,
repository,
service,
)
class Author(base.UUIDBase):
__tablename__ = "flask_author"
name: Mapped[str]
dob: Mapped[datetime.date | None]
class AuthorSchema(Struct):
id: UUID | None = None
name: str
dob: datetime.date | None = None
class AuthorService(service.SQLAlchemySyncRepositoryService[Author], FlaskServiceMixin):
class Repo(repository.SQLAlchemySyncRepository[Author]):
model_type = Author
repository_type = Repo
alchemy = AdvancedAlchemy(
SQLAlchemySyncConfig(connection_string="sqlite:///local.db", commit_mode="autocommit"),
app,
)
@app.route("/authors", methods=["GET"])
def list_authors():
current_page = request.args.get("currentPage", 1, type=int)
page_size = request.args.get("pageSize", 10, type=int)
limit_offset = filters.LimitOffset(limit=page_size, offset=page_size * (current_page - 1))
author_service = AuthorService(session=alchemy.get_sync_session())
results, total = author_service.get_many_and_count(limit_offset)
payload = author_service.to_schema(
results,
total,
filters=[limit_offset],
schema_type=AuthorSchema,
)
return author_service.jsonify(payload)
@app.route("/authors", methods=["POST"])
def create_author():
author_service = AuthorService(session=alchemy.get_sync_session())
author = author_service.create(data=request.get_json())
return author_service.jsonify(author_service.to_schema(author, schema_type=AuthorSchema))
Database Migrations¶
When the Flask extension is initialized, database commands are added to the Flask CLI:
flask database init
flask database revision --autogenerate -m "add users table"
flask database upgrade
flask database downgrade
flask database history