FLASK-SQLALCHEMY(1) Flask-SQLAlchemy FLASK-SQLALCHEMY(1) (NAME) flask-sqlalchemy - Flask SQLAlchemy [] Flask-SQLAlchemy Flask SQLAlchemy . (session) (models) (engines) SQLAlchemy Flask . Flask-SQLAlchemy SQLAlchemy . ORM SQLAlchemy . SQLAlchemy. (USER GUIDE) Flask-SQLAlchemy SQLAlchemy SQLAlchemy . SQLAlchemy . Flask-SQLAlchemy . API SQLAlchemy <#flask_sqlalchemy.SQLAlchemy> . SQLAlchemy Flask-SQLAlchemy (wrapper) SQLAlchemy . SQLAlchemy . Flask-SQLAlchemy SQLAlchemy. Flask-SQLAlchemy (scoped session) SQLAlchemy . SQLAlchemy 2.x API (type hints) (data classes) . SQLAlchemy 1.x (Legacy Quickstart) <> . Flask-SQLAlchemy PyPI . pip: $ pip install -U Flask-SQLAlchemy db SQLAlchemy . DeclarativeBase DeclarativeBaseNoMeta . from flask import Flask from flask_sqlalchemy import SQLAlchemy from sqlalchemy.orm import DeclarativeBase class Base(DeclarativeBase): pass db = SQLAlchemy(model_class=Base) (Models and Tables) <> ..SS SQLAlchemy db db.Model <#flask_sqlalchemy .SQLAlchemy.Model> db.session <#flask_sqlalchemy.SQLAlchemy.session> . SQLAlchemy <#flask_sqlalchemy.SQLAlchemy> . Flask . Flask SQLALCHEMY_DATABASE_URI <# flask_sqlalchemy.config.SQLALCHEMY_DATABASE_URI> . SQLAlchemy . Flask db.init_app <#flask_sqlalchemy.SQLAlchemy .init_app> SQLAlchemy <# flask_sqlalchemy.SQLAlchemy> . SQLite instance . # create the app app = Flask(__name__) # configure the SQLite database, relative to the app instance folder app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///project.db" # initialize the app with the extension db.init_app(app) Configuration <> . db.Model . CamelCase snake_case . from sqlalchemy import Integer, String from sqlalchemy.orm import Mapped, mapped_column class User(db.Model): id: Mapped[int] = mapped_column(Integer, primary_key=True) username: Mapped[str] = mapped_column(String, unique=True, nullable=False) email: Mapped[str] = mapped_column(String) Models and Tables <> . SQLAlchemy.create_all() <#flask_sqlalchemy.SQLAlchemy.create_all> . (application context) . . with app.app_context(): db.create_all() create_all (import) SQLAlchemy . create_all . (migration) Alembic Flask-Alembic Flask-Migrate . view Flask CLI db.session . SQLAlchemy __init__ . db.session.add(obj) (session) . . db.session.delete(obj) . db.session.commit() . db.session.execute(db.select(...)) . SQLAlchemy select . Result.scalars() Result.scalar() . @app.route("/users") def user_list(): users = db.session.execute(db.select(User).order_by(User.username)).scalars() return render_template("user/list.html", users=users) @app.route("/users/create", methods=["GET", "POST"]) def user_create(): if request.method == "POST": user = User( username=request.form["username"], email=request.form["email"], ) db.session.add(user) db.session.commit() return redirect(url_for("user_detail", id=user.id)) return render_template("user/create.html") @app.route("/user/") def user_detail(id): user = db.get_or_404(User, id) return render_template("user/detail.html", user=user) @app.route("/user//delete", methods=["GET", "POST"]) def user_delete(id): user = db.get_or_404(User, id) if request.method == "POST": db.session.delete(user) db.session.commit() return redirect(url_for("user_list")) return render_template("user/delete.html", user=user) Model.query . SQLAlchemy (legacy) . db.session.execute(db.select(...)) . Modifying and Querying Data <> ..SS SQLAlchemy . SQLAlchemy <# flask_sqlalchemy.SQLAlchemy> : o SQLAlchemy.Model <#flask_sqlalchemy.SQLAlchemy.Model>. __tablename__ . o SQLAlchemy.session <#flask_sqlalchemy.SQLAlchemy .session> (application context) Flask . . o SQLAlchemy.metadata <#flask_sqlalchemy.SQLAlchemy.metadata> SQLAlchemy.metadatas <#flask_sqlalchemy.SQLAlchemy.metadatas> . o SQLAlchemy.engine <#flask_sqlalchemy.SQLAlchemy.engine> SQLAlchemy.engines <#flask_sqlalchemy.SQLAlchemy.engines> . o SQLAlchemy.create_all() <#flask_sqlalchemy.SQLAlchemy.create_all> . o Flask . SQLAlchemy.init_app() <#flask_sqlalchemy.SQLAlchemy.init_app> app.config Flask . . . flask_sqlalchemy.config.SQLALCHEMY_DATABASE_URI (URI) . URL SQLAlchemy . Engine Configuration . SQLALCHEMY_BINDS . 3.0: SQLite (in-memory) . flask_sqlalchemy.config.SQLALCHEMY_ENGINE_OPTIONS sqlalchemy.create_engine() . engine_options SQLAlchemy <#flask_sqlalchemy .SQLAlchemy> . 3.0: (bind) . 2.4. flask_sqlalchemy.config.SQLALCHEMY_BINDS (bind) . URL SQLAlchemy url sqlalchemy.create_engine() . None SQLALCHEMY_ENGINE_OPTIONS SQLALCHEMY_DATABASE_URI . SQLALCHEMY_DATABASE_URI . 0.12. flask_sqlalchemy.config.SQLALCHEMY_ECHO echo echo_pool . SQLAlchemy . 3.0: echo echo_pool . flask_sqlalchemy.config.SQLALCHEMY_RECORD_QUERIES . get_recorded_queries() <#flask_sqlalchemy.record_queries.get_recorded_queries> . 3.0: (debug) (testing) . flask_sqlalchemy.config.SQLALCHEMY_TRACK_MODIFICATIONS insert update delete session.commit() models_committed <# flask_sqlalchemy.track_modifications.models_committed> before_models_committed <#flask_sqlalchemy.track_modifications .before_models_committed> . (overhead) . SQLAlchemy's ORM Events . 3.0: . 2.0. 3.1: SQLALCHEMY_COMMIT_ON_TEARDOWN . 3.0: SQLALCHEMY_NATIVE_UNICODE SQLALCHEMY_POOL_SIZE SQLALCHEMY_POOL_TIMEOUT SQLALCHEMY_POOL_RECYCLE SQLALCHEMY_MAX_OVERFLOW ..SS URL (syntax) SQLAlchemy . URL . . dialect://username:password@host:port/database : # SQLite, relative to Flask instance path sqlite:///project.db # PostgreSQL postgresql://scott:tiger@localhost/project # MySQL / MariaDB mysql://scott:tiger@localhost/project SQLite URL __ . dbname . __ ( ) . instance_path Flask . SQLite MySQL . SQLite (instance path) Flask . (In-memory) check_same_thread . MySQL ( MariaDB) 2013: Lost connection to MySQL server during query . pool_recycle ( ) . Flask-SQLAlchemy . SQLALCHEMY_DATABASE_URI SQLALCHEMY_ENGINE_OPTIONS . o engine_options SQLAlchemy <# flask_sqlalchemy.SQLAlchemy> . SQLALCHEMY_ECHO echo echo_pool . o SQLALCHEMY_BINDS . o SQLALCHEMY_ENGINE_OPTIONS None SQLALCHEMY_BINDS SQLALCHEMY_DATABASE_URI url . . MySQL MariaDB . 2013: Lost connection to MySQL server during query . pool_recycle . pool_pre_ping . SQLAlchemy ..SS (Models and Tables) db.Model db.Table . (bind keys) Flask-SQLAlchemy (engine) . (Initializing the Base Class) SQLAlchemy 2.x : DeclarativeBase DeclarativeBaseNoMeta . : from flask import Flask from flask_sqlalchemy import SQLAlchemy from sqlalchemy.orm import DeclarativeBase class Base(DeclarativeBase): pass SQLAlchemy (data classes) MappedAsDataclass . from sqlalchemy.orm import DeclarativeBase, MappedAsDataclass class Base(DeclarativeBase, MappedAsDataclass): pass SQLAlchemy <#flask_sqlalchemy.SQLAlchemy> MetaData . (constraint naming convention) . (migrations) Alembic . from sqlalchemy import MetaData class Base(DeclarativeBase): metadata = MetaData(naming_convention={ "ix": 'ix_%(column_0_label)s', "uq": "uq_%(table_name)s_%(column_0_name)s", "ck": "ck_%(table_name)s_%(constraint_name)s", "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s", "pk": "pk_%(table_name)s" }) (Initialize the Extension) db SQLAlchemy . db = SQLAlchemy(model_class=Base) (Defining Models) (declarative) SQLAlchemy . db.Model . SQLAlchemy __tablename__ Flask-SQLAlchemy . from sqlalchemy.orm import Mapped, mapped_column class User(db.Model): id: Mapped[int] = mapped_column(db.Integer, primary_key=True) username: Mapped[str] = mapped_column(db.String, unique=True, nullable=False) email: Mapped[str] = mapped_column(db.String) . create_all() <# flask_sqlalchemy.SQLAlchemy.create_all> . create_all (import) SQLAlchemy . with app.app_context(): db.create_all() SQLAlchemy . db.Table . . SQLAlchemy metadata . metadata bind_key . (many-to-many) . (association table) . import sqlalchemy as sa user_book_m2m = db.Table( "user_book", sa.Column("user_id", sa.ForeignKey(User.id), primary_key=True), sa.Column("book_id", sa.ForeignKey(Book.id), primary_key=True), ) (Reflecting Tables) SQLAlchemy (schema) . (reflection) . __table__ . reflect() <#flask_sqlalchemy.SQLAlchemy.reflect> . bind key . tables metadata . with app.app_context(): db.reflect() class User: __table__ = db.metadatas["auth"].tables["user"] . . (IDE) Alembic . (Modifying and Querying Data) (Insert, Update, Delete) ORM ORM SQLAlchemy SQLAlchemy . db.session.add() : user = User() db.session.add(user) db.session.commit() : user.verified = True db.session.commit() db.session.delete() : db.session.delete(user) db.session.commit() db.session.commit() (commit) . ..SS Select ORM SQLAlchemy SQLAlchemy . db.session.execute() . select() . select Result . user = db.session.execute(db.select(User).filter_by(username=username)).scalar_one() users = db.session.execute(db.select(User).order_by(User.username)).scalars() (Queries for Views) view Flask 404 Not Found . Flask-SQLAlchemy . o SQLAlchemy.get_or_404() <#flask_sqlalchemy.SQLAlchemy .get_or_404> 404 . o SQLAlchemy.first_or_404() <#flask_sqlalchemy.SQLAlchemy .first_or_404> 404 . o SQLAlchemy.one_or_404() <#flask_sqlalchemy.SQLAlchemy .one_or_404> 404 . @app.route("/user-by-id/") def user_by_id(id): user = db.get_or_404(User, id) return render_template("show_user.html", user=user) @app.route("/user-by-username/") def user_by_username(username): user = db.one_or_404(db.select(User).filter_by(username=username)) return render_template("show_user.html", user=user) 404 : user = db.one_or_404( db.select(User).filter_by(username=username), description=f"No user named '{username}'." ) (Legacy Query Interface) Model.query session.query . SQLAlchemy (legacy) . session.execute(select(...)) . Legacy Query Interface <> . (Paging Query Results) . pagination () paginate . SQLAlchemy.paginate() <#flask_sqlalchemy.SQLAlchemy.paginate> select Pagination <#flask_sqlalchemy .pagination.Pagination> . page per_page request.args . max_per_page . . page = db.paginate(db.select(User).order_by(User.join_date)) return render_template("user/list.html", page=page) Pagination.items <#flask_sqlalchemy.pagination.Pagination .items> Pagination <#flask_sqlalchemy.pagination .Pagination> . .
    {% for user in page %}
  • {{ user.username }} {% endfor %}
Pagination <#flask_sqlalchemy.pagination.Pagination> . iter_pages() <# flask_sqlalchemy.pagination.Pagination.iter_pages> None . . . users.iter_pages() [1, 2, None, 5, 6, 7, 8, 9, 10, 11, None, 19, 20] total <#flask_sqlalchemy .pagination.Pagination.total> first <# flask_sqlalchemy.pagination.Pagination.first> last <# flask_sqlalchemy.pagination.Pagination.last> . Jinja . {% macro render_pagination(pagination, endpoint) %}
{{ pagination.first }} - {{ pagination.last }} of {{ pagination.total }}
{% endmacro %} Flask db.engine db.session Flask . CLI . . current_app . Flask CLI (push) . CLI . . RuntimeError: Working outside of application context. This typically means that you attempted to use functionality that needed the current application. To solve this, set up an application context with app.app_context(). See the documentation for more information. app_context (push) . db.create_all . def create_app(): app = Flask(__name__) app.config.from_object("project.config") import project.models with app.app_context(): db.create_all() return app Flask endpoint . (push) . push . (application context) session . def test_user_model(app): user = User() with app.app_context(): db.session.add(user) db.session.commit() fixture pytest . import pytest @pytest.fixture def app_ctx(app): with app.app_context(): yield @pytest.mark.usefixtures("app_ctx") def test_user_model(): user = User() db.session.add(user) db.session.commit() (Multiple Databases with Binds) SQLAlchemy . "binds" () . Flask-SQLAlchemy "bind key" bind key . (session) bind key . bind key . (Configuring Binds) SQLALCHEMY_DATABASE_URI <#flask_sqlalchemy .config.SQLALCHEMY_DATABASE_URI> SQLALCHEMY_ENGINE_OPTIONS <# flask_sqlalchemy.config.SQLALCHEMY_ENGINE_OPTIONS> . SQLALCHEMY_BINDS <#flask_sqlalchemy.config .SQLALCHEMY_BINDS> bind key URL . URL "url" . SQLALCHEMY_DATABASE_URI = "postgresql:///main" SQLALCHEMY_BINDS = { "meta": "sqlite:////path/to/meta.db", "auth": { "url": "mysql://localhost/users", "pool_recycle": 3600, }, } (Defining Models and Tables with Binds) Flask-SQLAlchemy metadata . bind key metadata session . __bind_key__ . bind key None . class User(db.Model): __bind_key__ = "auth" id = db.Column(db.Integer, primary_key=True) bind key (override) . bind_key . user_table = db.Table( "user", db.Column("id", db.Integer, primary_key=True), bind_key="auth", ) session bind key metadata . bind key ..SS (Accessing Metadata and Engines) bind . session engine. SQLAlchemy.engine <# flask_sqlalchemy.SQLAlchemy.engine> SQLAlchemy.metadata <#flask_sqlalchemy.SQLAlchemy .metadata> . SQLAlchemy.engines <#flask_sqlalchemy.SQLAlchemy .engines> SQLAlchemy.metadatas <#flask_sqlalchemy.SQLAlchemy .metadatas> bind . (Creating and Dropping Tables) create_all() <#flask_sqlalchemy.SQLAlchemy .create_all> drop_all() <#flask_sqlalchemy.SQLAlchemy.drop_all> bind . bind_key None bind None bind . engine application context . # create tables for all binds db.create_all() # create tables for the default and "auth" binds db.create_all(bind_key=[None, "auth"]) # create tables for the "meta" bind db.create_all(bind_key="meta") # drop tables for the default bind db.drop_all(bind_key=None) (Recording Query Information) : . Flask-SQLAlchemy . . select . SQLALCHEMY_RECORD_QUERIES <#flask_sqlalchemy.config .SQLALCHEMY_RECORD_QUERIES> Flask True . get_recorded_queries() <#flask_sqlalchemy.record_queries .get_recorded_queries> . : statement SQL SQLAlchemy . parameters SQL. start_time / end_time . . duration . location . . (Tracking Modifications) : . SQLAlchemy . Flask-SQLAlchemy session Blinker session.flush() session.commit() . SQLALCHEMY_TRACK_MODIFICATIONS <#flask_sqlalchemy.config .SQLALCHEMY_TRACK_MODIFICATIONS> Flask . models_committed <#flask_sqlalchemy .track_modifications.models_committed> ( commit ) before_models_committed <# flask_sqlalchemy.track_modifications.before_models_committed> ( commit ) . from flask_sqlalchemy.track_modifications import models_committed def get_modifications(sender: Flask, changes: list[tuple[t.Any, str]]) -> None: ... models_committed.connect(get_modifications) SQLAlchemy <#flask_sqlalchemy.SQLAlchemy> . SQLAlchemy . Flask-SQLAlchemy db.Model . model_class . (joined-table inheritance) . : ( ) . from sqlalchemy import Integer, String, ForeignKey from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, declared_attr class Base(DeclarativeBase): @declared_attr.cascading @classmethod def id(cls): for base in cls.__mro__[1:-1]: if getattr(base, "__table__", None) is not None: return mapped_column(ForeignKey(base.id), primary_key=True) else: return mapped_column(Integer, primary_key=True) db = SQLAlchemy(app, model_class=Base) class User(db.Model): name: Mapped[str] = mapped_column(String) class Employee(User): title: Mapped[str] = mapped_column(String) . . from datetime import datetime from sqlalchemy import DateTime, Integer, String from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, declared_attr class TimestampModel(db.Model): __abstract__ = True created: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=datetime.utcnow) updated: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) class Author(db.Model): id: Mapped[int] = mapped_column(Integer, primary_key=True) username: Mapped[str] = mapped_column(String, unique=True, nullable=False) class Post(TimestampModel): id: Mapped[int] = mapped_column(Integer, primary_key=True) title: Mapped[str] = mapped_column(String, nullable=False) (mixin) db.Model . class TimestampMixin: created: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=datetime.utcnow) updated: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) class Post(TimestampMixin, db.Model): id: Mapped[int] = mapped_column(Integer, primary_key=True) title: Mapped[str] = mapped_column(String, nullable=False) __tablename__ Flask-SQLAlchemy . __tablename__ . disable_autonaming=True SQLAlchemy . class Base(sa_orm.DeclarativeBase): pass db = SQLAlchemy(app, model_class=Base, disable_autonaming=True) Session (Session Class) Session <#flask_sqlalchemy.session.Session> Flask-SQLAlchemy bind . (horizontal sharding) session . class_ session_options session . Flask-SQLAlchemy db session . db.engines . from sqlalchemy.ext.horizontal_shard import ShardedSession from flask_sqlalchemy.session import Session class CustomSession(ShardedSession, Session): ... db = SQLAlchemy(session_options={"class_": CustomSession}) Query (Query Class) : query SQLAlchemy (legacy) . session.query Model.query db.Query lazy="dynamic" . session.execute(select(...)) . (query) session . query . get_or . from flask_sqlalchemy.query import Query class GetOrQuery(Query): def get_or(self, ident, default=None): out = self.get(ident) if out is None: return default return out db = SQLAlchemy(query_class=GetOrQuery) user = User.query.get_or(user_id, anonymous_user) query_class db.Query db.session.query Model.query db.relationship(lazy="dynamic") . . query query_class . class User(db.Model): query_class = GetOrQuery (dynamic) query_class . db.relationship(User, lazy="dynamic", query_class=GetOrQuery) session.query query_cls session_options . db = SQLAlchemy(session_options={"query_cls": GetOrQuery}) API (Extension) class flask_sqlalchemy.SQLAlchemy(app=None, *, metadata=None, session_options=None, query_class=, model_class=, engine_options=None, add_models_to_shell=True, disable_autonaming=False) SQLAlchemy Flask . (engine) (sessions) . . init_app() . Model Table . init_app() . session engine (application context) Flask . create_all() . sqlalchemy sqlalchemy.orm SQLAlchemy . sqlalchemy.Column sqlalchemy.orm.relationship db.Column db.relationship . . (Parameters) o app (Flask | None) -- init_app() Flask. o metadata (sa.MetaData | None) -- sqlalchemy.schema.MetaData . (naming convention) . o session_options (dict [str , t.Any] | None) -- session . scopefunc (scoped session) . sqlalchemy.orm.sessionmaker . o query_class (type [Query <#flask_sqlalchemy.query .Query>]) -- (query) . SQLAlchemy (legacy) . o model_class (_FSA_MCT) -- Model. . o engine_options (dict [str , t.Any] | None) -- . . sqlalchemy.create_engine() . o add_models_to_shell (bool ) -- db flask shell. o disable_autonaming (bool ) 3.1.0: metadata SQLAlchemy 1.x SQLAlchemy 2.x . Base . 3.1.0: disable_autonaming . 3.1.0: model_class declarative base SQLAlchemy 2.x . 3.0: session engine Flask . 3.0: bind key metadata . 3.0: engine_options . 3.0: session_options . 3.0: add_models_to_shell . 3.0: init_app . 3.0: app (keyword-only) . 3.0: app.extensions["sqlalchemy"] . 3.0: . . 3.0: use_native_unicode . 2.4: engine_options . 2.1: metadata query_class model_class . 2.1: session Model.query Query. 0.16: scopefunc session_options . 0.10: session_options . Model SQLAlchemy. . __tablename__ CamelCase snake_case . (single-table inheritance) . __bind_key__ . metadata engine . metadata __table__ . API 1.x SQLAlchemy Model model_class . (metaclass) . API 2.x SQLAlchemy sqlalchemy.orm.DeclarativeBase sqlalchemy.orm.DeclarativeBaseNoMeta model_class . Query Model.query lazy="dynamic". : query SQLAlchemy (legacy) . query_class . Table sqlalchemy.schema.Table . Table metadata . bind_key . (Parameters) o bind_key -- . o args -- . (constraints) . o kwargs -- . 3.0: Table SQLAlchemy . create_all(bind_key='__all__') metadata.create_all() bind . (migration) . (application context) Flask . bind_key (str | None | list [str | None]) -- bind . bind . None 3.0: bind bind_key . app . 0.12: bind app . drop_all(bind_key='__all__') metadata.drop_all() bind . (application context) Flask . bind_key (str | None | list [str | None]) -- bind . bind . None 3.0: bind bind_key . app . 0.12: bind app . dynamic_loader(argument, **kwargs) sqlalchemy.orm.dynamic_loader() Query backref . 3.0: Query backref . o argument (Any ) o kwargs (Any ) RelationshipProperty [Any ] property engine: Engine (Engine ) bind Model Table session . SQLALCHEMY_ENGINE_OPTIONS <#flask_sqlalchemy.config .SQLALCHEMY_ENGINE_OPTIONS> engine_options . (application context) Flask . property engines: Mapping [str | None , Engine ] bind sqlalchemy.engine.Engine . None engine . SQLALCHEMY_BINDS <# flask_sqlalchemy.config.SQLALCHEMY_BINDS> engine_options . (application context) Flask . 3.0. first_or_404(statement, *, description=None) Result.scalar() None 404 Not Found . o statement (Select ) -- select . o description (str | None) -- . Any 3.0. get_engine(bind_key=None, **kwargs) bind . (application context) Flask . o bind_key (str | None) -- . o kwargs (Any ) Engine 3.0: Flask-SQLAlchemy 3.2 . engines[key] . 3.0: bind bind_key . app . get_or_404(entity, ident, *, description=None, **kwargs) session.get() None 404 Not Found . o entity (type [_O]) -- . o ident (Any ) -- . o description (str | None) -- . o kwargs (Any ) -- session.get(). _O 3.1: session.get(). 3.0. init_app(app) Flask . session ..sp (engines) bind key . . . app.config : o SQLALCHEMY_DATABASE_URI <#flask_sqlalchemy .config.SQLALCHEMY_DATABASE_URI> o SQLALCHEMY_ENGINE_OPTIONS <#flask_sqlalchemy .config.SQLALCHEMY_ENGINE_OPTIONS> o SQLALCHEMY_ECHO <#flask_sqlalchemy.config .SQLALCHEMY_ECHO> o SQLALCHEMY_BINDS <#flask_sqlalchemy.config .SQLALCHEMY_BINDS> o SQLALCHEMY_RECORD_QUERIES <#flask_sqlalchemy .config.SQLALCHEMY_RECORD_QUERIES> o SQLALCHEMY_TRACK_MODIFICATIONS <# flask_sqlalchemy.config .SQLALCHEMY_TRACK_MODIFICATIONS> (Parameters) app (Flask ) -- Flask . (Return type) None property metadata: MetaData Model Table bind key . metadatas: dict [str | None , MetaData ] bind key sqlalchemy.schema.MetaData . None metadata . metadata . (naming convention) . bind key . 3.0. one_or_404(statement, *, description=None) Result.scalar_one() NoResultFound MultipleResultsFound 404 Not Found . (Parameters) o statement (Select ) -- select . o description (str | None) -- . (Return type) Any 3.0. paginate(select, *, page=None, per_page=None, max_per_page=None, error_out=True, count=True) offset limit select Pagination . select(User). unique() scalars() select . (Parameters) o select (Select ) -- select . o page (int | None) -- offset. page 1 . o per_page (int | None) -- offset limit. per_page 20 . o max_per_page (int | None) -- per_page . None . 100 . o error_out (bool ) -- 404 Not Found page 1 page per_page 1 . o count (bool ) -- count . . (Return type) Pagination <#flask_sqlalchemy.pagination .Pagination> 3.0: count . 3.0. reflect(bind_key='__all__') metadata.reflect() bind key. Flask (application context) . (Parameters) bind_key (str | None | list [str | None]) -- bind key (reflect) . bind . (Return type) None 3.0: bind bind_key. app . 0.12: bind app . relationship(*args, **kwargs) sqlalchemy.orm.relationship() Query backref . 3.0: Query backref . (Parameters) o args (Any ) o kwargs (Any ) (Return type) RelationshipProperty [Any ] session sqlalchemy.orm.scoping.scoped_session Session Flask . (pool) . session_options . Flask . 3.0: . class flask_sqlalchemy.model.Model SQLAlchemy.Model. db.Model . db.Model model_class SQLAlchemy . db.Model model_class . __bind_key__ (bind key) . metadata __table__ . None . __tablename__ . SQLAlchemy Flask-SQLAlchemy . __table__ __tablename__ . query: t.ClassVar[Query <#flask_sqlalchemy.query.Query>] SQLAlchemy . db.session.query(Model). query_class . : (query interface) SQLAlchemy (legacy) . session.execute(select()) . query_class query . SQLAlchemy.Query Query . Query (SQLAlchemy 1.x) API SQLAlchemy 1.x ( model_class ) Model . class flask_sqlalchemy.model.DefaultMeta(name, bases, d, **kwargs) SQLAlchemy __bind_key__ __tablename__ . (Parameters) o name (str ) o bases (tuple [type , ...]) o d (dict [str , t.Any]) o kwargs (t.Any) class flask_sqlalchemy.model.BindMetaMixin(name, bases, d, **kwargs) metadata __bind_key__ . metadata __table__ __bind_key__ . metadata . (Parameters) o name (str ) o bases (tuple [type , ...]) o d (dict [str , t.Any]) o kwargs (t.Any) class flask_sqlalchemy.model.NameMetaMixin(name, bases, d, **kwargs) __tablename__ CamelCase snake_case . (non-abstract) __tablename__ . (single-table inheritance) __table__ . (Parameters) o name (str ) o bases (tuple [type , ...]) o d (dict [str , t.Any]) o kwargs (t.Any) class flask_sqlalchemy.session.Session(db, **kwargs) Session SQLAlchemy (engine) bind key . db.session class_ session_options SQLAlchemy . 3.0: SignallingSession . (Parameters) o db (SQLAlchemy <#flask_sqlalchemy.SQLAlchemy>) o kwargs (t.Any) get_bind(mapper=None, clause=None, bind=None, **kwargs) engine bind_key . bind key bind . 3.0.3: bind (joined inheritance). 3.0: SQLAlchemy . 2.1: (transaction) . (Parameters) o mapper (Any | None) o clause (Any | None) o bind (Engine | Connection | None) o kwargs (Any ) (Return type) Engine | Connection Pagination class flask_sqlalchemy.pagination.Pagination offset limit . . SQLAlchemy.paginate() Query.paginate() . 3.0: . 3.0: (public API) . page: int . per_page: int . items: list [Any ] . . total: int | None . property first: int . 3.0. property last: int ( ) . 3.0. property pages: int . property has_prev: bool True . property prev_num: int | None None . prev(*, error_out=False) Pagination . (Parameters) error_out (bool ) -- 404 Not Found page page per_page (int) . (Return type) Pagination <#flask_sqlalchemy.pagination .Pagination> property has_next: bool True . property next_num: int | None None . next(*, error_out=False) Pagination . (Parameters) error_out (bool ) -- 404 Not Found page page per_page (int) . (Return type) Pagination <#flask_sqlalchemy.pagination .Pagination> iter_pages(*, left_edge=2, left_current=2, right_current=4, right_edge=2) . None . . 1, 2, None, 5, 6, 7, 8, 9, 10, 11, None, 19, 20 o left_edge (int ) -- . o left_current (int ) -- . o right_current (int ) -- . o right_edge (int ) -- . Iterator [int | None] 3.0: yield . 3.0: right_current (inclusive) . 3.0: (keyword-only) . Query class flask_sqlalchemy.query.Query(entities, session=None) Query SQLAlchemy . Model.query . 3.0: BaseQuery Query . o entities (Union[_ColumnsClauseArgument[Any], Sequence[_ColumnsClauseArgument[Any]]]) o session (Optional[Session <#flask_sqlalchemy.session .Session>]) first_or_404(description=None) first() None 404 Not Found . description (str | None) -- . Any get_or_404(ident, description=None) get() None 404 Not Found . o ident (Any ) -- (primary key) . o description (str | None) -- . Any one_or_404(description=None) one() NoResultFound MultipleResultsFound 404 Not Found . description (str | None) -- . Any 3.0. paginate(*, page=None, per_page=None, max_per_page=None, error_out=True, count=True) offset limit Pagination . o page (int | None) -- offset . page 1 . o per_page (int | None) -- offset limit . per_page 20 . o max_per_page (int | None) -- per_page . None . 100 . o error_out (bool ) -- page 1 page per_page 1 int 404 Not Found . o count (bool ) -- count . . Pagination <#flask_sqlalchemy.pagination .Pagination> 3.0: (keyword-only) . 3.0: count . 3.0: max_per_page 100 . flask_sqlalchemy.record_queries.get_recorded_queries() (session) . SQLALCHEMY_RECORD_QUERIES <#flask_sqlalchemy.config .SQLALCHEMY_RECORD_QUERIES> . : statement SQL SQLAlchemy . parameters SQL. start_time / end_time . . duration . location . . 3.0: get_debug_queries. 3.0: dataclass . 3.0: context location . 3.0: . (Return type) list [_QueryInfo] (Track Modifications) flask_sqlalchemy.track_modifications.models_committed Blinker (commit) . . changes (instance, operation) . "insert" "update" "delete". flask_sqlalchemy.track_modifications.before_models_committed models_committed commit . (ADDITIONAL INFORMATION) BSD-3-Clause (BSD-3-Clause License) 2010 Pallets : 1. . 2. / . 3. . << >> ("AS IS") . ( ) ( ) ..SS " (Changes)" 3.1.1 (Version 3.1.1) 2023-09-11 o __version__ . importlib.metadata.version("flask-sqlalchemy") . #5230 3.1.0 (Version 3.1.0) 2023-09-11 o Python 3.7. #1251 o API 2.x SQLAlchemy model_class. #1140 o SQLAlchemy 2.0.16. o . o get_or_404 session.get. #1149 o bind key clause. #1211 3.0.5 (Version 3.0.5) 2023-06-21 o Pagination.next() max_per_page . #1201 o (type hint) get_or_404 non-optional. #1226 3.0.4 (Version 3.0.4) 2023-06-19 o get_or_404. #1208 o pyright ( Pylance VS Code). #1205 3.0.3 (Version 3.0.3) 2023-01-31 o SQLAlchemy init_app. #1151 o engine (polymorphic) . #1155 3.0.2 (Version 3.0.2) 2022-10-14 o SQLAlchemy 2. #1122 3.0.1 (Version 3.0.1) 2022-10-11 o (typing) typeshed. #1112 o engine SQLALCHEMY_DATABASE_URI bind . #1117 3.0.0 (Version 3.0.0) 2022-10-04 o Python 2 3.4 3.5 3.6. o Flask 2.2. o SQLAlchemy 1.4.18. o . o (session) thread (app context) . app context session . o session engine Flask . #508 #944 o bind MetaData SQLAlchemy . bind . o SQLALCHEMY_DATABASE_URI sqlite:///:memory: . SQLALCHEMY_BINDS engine . #731 o SQLite app.instance_path app.root_path. instance . #462 o get_or_404 first_or_404 one_or_404 paginate . query SQLAlchemy session.execute(select()) . #1088 o engine session (underscore) . . o SQLAlchemy app . o bind bind_key app SQLAlchemy. o __getattr__ SQLAlchemy . o app.extensions["sqlalchemy"] . #698 o class_ session_options . #327 o SignallingSession Session . o Session.get_bind . o db (import) flask shell . #1089 o CamelCase snake_case . Alembic __tablename__ . #406 o repr Model (transient) (pending) . #967 o __init_subclass__ . #1002 o db.Table . o engine_options . o SQLALCHEMY_BINDS bind URL URL . SQLALCHEMY_DATABASE_URI SQLALCHEMY_ENGINE_OPTIONS None . #783 o init_app . #698 o db.engines bind . o get_engine get_tables_for_bind get_binds . o URI SQLite sqlite:///file:name.db?uri=true . #998 #1045 o SQLite pool_size 0 NullPool . o MySQL "utf8mb4" . #875 o MySQL pool_size 10 . o MySQL queue pool pool_recycle . #803 o BaseQuery Query . o Query.one_or_404 . o query backref relationship . #417 o Pagination API . db.paginate query.paginate . #1088 .IP o 2 Pagination.iter_pages Query.paginate (keyword-only) . o Pagination (iterable) . #70 o . o Pagination.iter_pages . #622 o right_current Pagination.iter_pages (inclusive) . o per_page 0 . #1091 o max_per_page 100 . #1091 o Pagination.first last . #567 o SQLALCHEMY_RECORD_QUERIES app.debug app.testing . #1092 o get_debug_queries get_recorded_queries . o tuple dataclass . context location . . o SQLALCHEMY_TRACK_MODIFICATIONS . #727 o SQLALCHEMY_COMMIT_ON_TEARDOWN . . db.session.commit() . #216 2.5.1 2021-03-18 o Python 2.7. 2.5.0 2021-03-18 o SQLAlchemy 1.4. o URL SQLAlchemy . None URL . #885 2.4.4 2020-07-14 o mixin type. CPython 3.8.4 . #852 2.4.3 2020-05-26 o SQLALCHEMY_COMMIT_ON_TEARDOWN . db.session.commit() . #216 2.4.2 2020-05-25 o (de-duped) . #812 2.4.1 2019-09-24 o AttributeError bind (polymorphic). #651 2019-04-24 o Python 2.6 3.3. #687 o SQLAlchemy 1.3. #684 o engine. engine_options SQLALCHEMY_ENGINE_OPTIONS . engine SQLALCHEMY_NATIVE_UNICODE SQLALCHEMY_POOL_SIZE SQLALCHEMY_POOL_TIMEOUT SQLALCHEMY_POOL_RECYCLE SQLALCHEMY_MAX_OVERFLOW . #684 o get_or_404() first_or_404() description 404 . #636 o time.perf_counter Python 3 Windows. #638 o Flask Flaskr Flask-SQLAlchemy . #720 2.3.2 (Version 2.3.2) 2017-10-11 o (single-table inheritance). #561 2.3.1 (Version 2.3.1) 2017-10-05 o metadata . (reflected) . #551 o (primary key) . #556 o repr flush . #555 o max_per_page . #542 o paginate error_out=False page 1 per_page 0 . #558 2.3.0 (Version 2.3.0) 2017-09-28 o __tablename__. (single-table inheritance) . declared_attr . PrimaryKeyConstraint . #541 o declarative_base() model_class SQLAlchemy.__init__ . metaclass . #546 o DeclarativeMeta bind mixin . metaclass . #546 o metaclass models . _BoundDeclarativeMeta DefaultMeta 3.0 . #546 o repr . #530 o init_app current_app . . #547 2.2 (Version 2.2) 2017-02-27 Dubnium o SQLAlchemy sqlalchemy.inspect 0.8 . o query_class model_class SQLAlchemy. #328 o SQLAlchemy db.session. #364 o __bind_key__ . #373 o SQLALCHEMY_ECHO. #409 o SQLALCHEMY_DATABASE_URI . #443 o . #460 o Flask < 0.10. db (app context) teardown . #461 o declared_attr . #467 2015-10-23 Caesium o mixin . o MetaData . o binds session. 2.0 2014-08-29 Bohrium o Flask-SQLAlchemy. (attribute error) . o . o SignallingSession (hook) . o bind . o (table reflection). o autoflush. o SQLALCHEMY_COMMIT_ON_TEARDOWN . 1.0 2013-07-20 Aurum o Python 3.3 . o Python 2.5 . o . o (major) . 0.16 o (flask_sqlalchemy). o Flask 0.9. 0.15 o (session) . 0.14 o sqlite . 0.13 o Flask-SQLAlchemy (binds) . 0.12 o . o BaseQuery db.Query. o query_class db.relation db.relationship db.dynamic_loader BaseQuery. o Flask 0.7. o 0.10 . 0.10 o . o . o Model.query SQLAlchemy . None RuntimeError . o (session) . o __repr__ . o db.Table . . 0.9 o Flask. 0.8 o . o (connection recycling) MySQL. o Flask. 0.7 o (AUTHORS) Pallets (COPYRIGHT) 2010 Pallets 3.1.x December 15, 2025 FLASK-SQLALCHEMY(1)