Flask
The Flask helpers create a client, optionally run a read-only startup guard, and register one explicit migration command. Nothing in the wiring applies migrations — invoking the command does.
extra · dblift[flask]
Install
pip install "dblift[flask]"
App factory
app.py
from flask import Flask
from sqlalchemy import create_engine
from dblift.integrations.flask import init_dblift, register_cli
engine = create_engine("postgresql+psycopg://user:password@localhost/app")
def create_app() -> Flask:
app = Flask(__name__)
client = init_dblift(
app,
engine,
"migrations",
guard=True,
)
register_cli(app, client)
return appinit_dblift builds the client with DBLiftClient.from_sqlalchemy, stores it at app.extensions["dblift"] and returns it. With guard=True the startup check calls migration_guard(), which reads client.info() and raises if migrations are pending (on_pending="raise" by default). If the check itself errors, the client is closed before the error propagates.
Migration command
flask --app your_app:create_app dblift-migrate
register_cli adds this command to the Flask CLI. Running it is the explicit action that calls client.migrate().
Guard options
Use guard=False when your deploy applies migrations before the web app is created, or when the Flask CLI has to load the app while migrations are still pending.
app.py
client = init_dblift(app, engine, "migrations", guard=False)Reading status in a route
app.py
@app.get("/health")
def health():
client = app.extensions["dblift"]
info = client.info()
return {
"pending_count": len(getattr(info, "pending_migrations", []) or []),
}The engine stays yours
You own the Engine lifecycle. Closing the client releases DBLift resources and leaves your engine undisposed.