### Example Database Connection URLs Source: https://flask-sqlalchemy.readthedocs.io/en/stable/config Examples of connection strings for SQLite, PostgreSQL, and MySQL/MariaDB. ```text # SQLite, relative to Flask instance path sqlite:///project.db ``` ```text # PostgreSQL postgresql://scott:tiger@localhost/project ``` ```text # MySQL / MariaDB mysql://scott:tiger@localhost/project ``` -------------------------------- ### Install Flask-SQLAlchemy Source: https://flask-sqlalchemy.readthedocs.io/en/stable/quickstart Install or update Flask-SQLAlchemy to the latest version using pip. ```bash $ pip install -U Flask-SQLAlchemy ``` -------------------------------- ### Flask CRUD Operations with SQLAlchemy Source: https://flask-sqlalchemy.readthedocs.io/en/stable/quickstart Provides examples for listing, creating, detailing, and deleting users. Remember to call `db.session.commit()` after modifications. ```python from flask import Flask, request, redirect, url_for, render_template from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///project.db" db = SQLAlchemy(app) class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String, unique=True, nullable=False) email = db.Column(db.String, unique=True, nullable=False) def __repr__(self): return f'' @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) ``` -------------------------------- ### Runtime Error Example Source: https://flask-sqlalchemy.readthedocs.io/en/stable/contexts Illustrates the error encountered when attempting database operations outside an active application context. ```text 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. ``` -------------------------------- ### Example Pagination Iteration Source: https://flask-sqlalchemy.readthedocs.io/en/stable/pagination The `iter_pages()` method on the `Pagination` object yields page numbers, potentially separated by `None` to indicate ellipses. This example shows the output for 20 pages with the current page being 7. ```python users.iter_pages() [1, 2, None, 5, 6, 7, 8, 9, 10, 11, None, 19, 20] ``` -------------------------------- ### get_engine Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api Get the engine for the given bind key for the current application. Requires a Flask application context. ```APIDOC ## get_engine Get the engine for the given bind key for the current application. This requires that a Flask application context is active. Parameters: * **bind_key** (_str_ _|__None_) – The name of the engine. * **kwargs** (_Any_) Return type: _Engine_ Deprecated since version 3.0: Will be removed in Flask-SQLAlchemy 3.2. Use `engines[key]` instead. Changelog Changed in version 3.0: Renamed the `bind` parameter to `bind_key`. Removed the `app` parameter. ``` -------------------------------- ### Assign Reflected Table to Model (Specific Bind) Source: https://flask-sqlalchemy.readthedocs.io/en/stable/models This example demonstrates assigning a reflected table to a model when using a specific bind key (e.g., 'auth'). Access the metadata for the specific bind key via `db.metadatas`. ```python # From an "auth" bind key class User(db.Model): __table__ = db.metadatas["auth"].tables["user"] ``` -------------------------------- ### Define Base Class for Models Source: https://flask-sqlalchemy.readthedocs.io/en/stable/models Create a base class for your models by subclassing `DeclarativeBase`. This is the starting point for defining your ORM models. ```python from flask import Flask from flask_sqlalchemy import SQLAlchemy from sqlalchemy.orm import DeclarativeBase class Base(DeclarativeBase): pass ``` -------------------------------- ### Assign Reflected Table to Model (Default Bind) Source: https://flask-sqlalchemy.readthedocs.io/en/stable/models After reflection, you can assign a detected table object to a model's `__table__` attribute. This example shows assignment from the default bind key. ```python # From the default bind key class Book(db.Model): __table__ = db.metadata.tables["book"] ``` -------------------------------- ### Get or Raise 404 with Custom Message Source: https://flask-sqlalchemy.readthedocs.io/en/stable/queries You can provide a custom description to the 404 error raised by `one_or_404` when no matching record is found. ```python user = db.one_or_404( db.select(User).filter_by(username=username), description=f"No user named '{username}'." ) ``` -------------------------------- ### Get or Raise 404 for User by ID Source: https://flask-sqlalchemy.readthedocs.io/en/stable/queries Use `db.get_or_404()` to retrieve a model instance by its ID, raising a 404 error if not found. This is useful in view functions. ```python @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) ``` -------------------------------- ### Get or Raise 404 for User by Username Source: https://flask-sqlalchemy.readthedocs.io/en/stable/queries Use `db.one_or_404()` with a select statement to retrieve a single result, raising a 404 error if zero or more than one result is found. This is useful in view functions. ```python @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) ``` -------------------------------- ### SQLAlchemy Class Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api Integrates SQLAlchemy with Flask, handling engine setup, table/model association, and connection cleanup. It allows access to SQLAlchemy modules and provides a base for defining models. ```APIDOC ## class flask_sqlalchemy.SQLAlchemy(_app =None_, _*_, _metadata =None_, _session_options =None_, _query_class =Query_, _model_class =Model_, _engine_options =None_, _add_models_to_shell =True_, _disable_autonaming =False_) ### Description Integrates SQLAlchemy with Flask. This handles setting up one or more engines, associating tables and models with specific engines, and cleaning up connections and sessions after each request. ### Parameters: #### Parameters: - **app** (_Flask_ _|__None_) – Call `init_app()` on this Flask application now. - **metadata** (_sa.MetaData_ _|__None_) – Use this as the default `sqlalchemy.schema.MetaData`. Useful for setting a naming convention. - **session_options** (_dict_ _[__str_ _,__t.Any_ _]__|__None_) – Arguments used by `session` to create each session instance. A `scopefunc` key will be passed to the scoped session, not the session instance. See `sqlalchemy.orm.sessionmaker` for a list of arguments. - **query_class** (_type_ _[__Query_ _]_) – Use this as the default query class for models and dynamic relationships. The query interface is considered legacy in SQLAlchemy. - **model_class** (__FSA_MCT_) – Use this as the model base class when creating the declarative model class `Model`. Can also be a fully created declarative model class for further customization. - **engine_options** (_dict_ _[__str_ _,__t.Any_ _]__|__None_) – Default arguments used when creating every engine. These are lower precedence than application config. See `sqlalchemy.create_engine()` for a list of arguments. - **add_models_to_shell** (_bool_) – Add the `db` instance and all model classes to `flask shell`. - **disable_autonaming** (_bool_) – Disable autonaming for table names. ``` -------------------------------- ### Paginate Query Results Source: https://flask-sqlalchemy.readthedocs.io/en/stable/pagination Call `db.paginate()` on a select statement to get a `Pagination` object. This method takes `page` and `per_page` arguments from the query string `request.args` during a request. Use `max_per_page` to limit the number of results per page. ```python page = db.paginate(db.select(User).order_by(User.join_date)) return render_template("user/list.html", page=page) ``` -------------------------------- ### Manual Context for Table Creation Source: https://flask-sqlalchemy.readthedocs.io/en/stable/contexts Demonstrates how to manually push an application context to create database tables using `db.create_all()`. ```python def create_app(): app = Flask(__name__) app.config.from_object("project.config") import project.models with app.app_context(): db.create_all() return app ``` -------------------------------- ### init_app Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api Initialize a Flask application for use with this extension instance. Must be called before accessing database engine or session. ```APIDOC ## init_app Initialize a Flask application for use with this extension instance. This must be called before accessing the database engine or session with the app. This sets default configuration values, then configures the extension on the application and creates the engines for each bind key. Therefore, this must be called after the application has been configured. Changes to application config after this call will not be reflected. The following keys from `app.config` are used: * `SQLALCHEMY_DATABASE_URI` * `SQLALCHEMY_ENGINE_OPTIONS` * `SQLALCHEMY_ECHO` * `SQLALCHEMY_BINDS` * `SQLALCHEMY_RECORD_QUERIES` * `SQLALCHEMY_TRACK_MODIFICATIONS` Parameters: **app** (_Flask_) – The Flask application to initialize. Return type: None ``` -------------------------------- ### Initialize SQLAlchemy Extension Source: https://flask-sqlalchemy.readthedocs.io/en/stable/models Create the `db` object by instantiating `SQLAlchemy`, passing your custom base class to the `model_class` argument. ```python db = SQLAlchemy(model_class=Base) ``` -------------------------------- ### Create All Tables in Database Source: https://flask-sqlalchemy.readthedocs.io/en/stable/models After defining your models, use `db.create_all()` within the application context to create the corresponding tables in the database. Ensure all model submodules are imported beforehand. ```python with app.app_context(): db.create_all() ``` -------------------------------- ### Configure Multiple Database Binds Source: https://flask-sqlalchemy.readthedocs.io/en/stable/binds Set the default database URI and define additional binds using a dictionary mapping bind keys to URLs or configuration dictionaries. Engine options can be specified for each bind. ```python SQLALCHEMY_DATABASE_URI = "postgresql:///main" SQLALCHEMY_BINDS = { "meta": "sqlite:////path/to/meta.db", "auth": { "url": "mysql://localhost/users", "pool_recycle": 3600, }, } ``` -------------------------------- ### create_all Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api Creates database tables that do not exist. This method iterates through specified bind keys and calls `metadata.create_all()` for each, but it does not update existing tables. ```APIDOC ## create_all ### Description Create tables that do not exist in the database by calling `metadata.create_all()` for all or some bind keys. This does not update existing tables, use a migration library for that. This requires that a Flask application context is active. ### Parameters #### Path Parameters * **bind_key** (str | None | list[str | None]) - Optional - A bind key or list of keys to create the tables for. Defaults to all binds. ### Return type None ``` -------------------------------- ### flask_sqlalchemy.track_modifications.models_committed Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api A Blinker signal emitted after the session is committed if there were changed models. The receiver gets a 'changes' argument with a list of (instance, operation) tuples. ```APIDOC ## models_committed ### Description This Blinker signal is sent after the session is committed if there were changed models in the session. The sender is the application that emitted the changes. The receiver is passed the `changes` argument with a list of tuples in the form `(instance, operation)`. The operations are `"insert"`, `"update"`, and `"delete"`. ``` -------------------------------- ### Basic Database Connection URL Format Source: https://flask-sqlalchemy.readthedocs.io/en/stable/config Use this format for defining your database connection string. Username, password, host, and port are optional based on the database type. ```text dialect://username:password@host:port/database ``` -------------------------------- ### Configure Flask-SQLAlchemy Source: https://flask-sqlalchemy.readthedocs.io/en/stable/quickstart Initialize the SQLAlchemy extension with your Flask app. Ensure SQLALCHEMY_DATABASE_URI is set in your app's configuration. ```python from flask import Flask from flask_sqlalchemy import SQLAlchemy # 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 = SQLAlchemy() db.init_app(app) ``` -------------------------------- ### Create and Drop Tables for Specific Binds Source: https://flask-sqlalchemy.readthedocs.io/en/stable/binds Control table creation and dropping operations for specific binds using the `bind_key` argument in `create_all()` and `drop_all()`. These methods require an application context. ```python # 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) ``` -------------------------------- ### Render Simple Pagination Widget Source: https://flask-sqlalchemy.readthedocs.io/en/stable/pagination This Jinja macro demonstrates how to create a simple pagination widget using attributes like `first`, `last`, `total`, and `iter_pages()` from the `Pagination` object. ```html {% macro render_pagination(pagination, endpoint) %}
{{ pagination.first }} - {{ pagination.last }} of {{ pagination.total }}
{% endmacro %} ``` -------------------------------- ### Manual Context for Model Testing Source: https://flask-sqlalchemy.readthedocs.io/en/stable/contexts Shows how to push an application context within a test to interact with the database session for model operations. ```python def test_user_model(app): user = User() with app.app_context(): db.session.add(user) db.session.commit() ``` -------------------------------- ### get_or_404 Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api Like session.get() but aborts with a 404 Not Found error instead of returning None. ```APIDOC ## get_or_404 Like `session.get()` but aborts with a `404 Not Found` error instead of returning `None`. ``` -------------------------------- ### first_or_404 Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api Retrieves the first object in the query result. If no object is found, it aborts with a 404 Not Found error. ```APIDOC ## first_or_404 ### Description Retrieves the first object in the query result. If no object is found, it aborts with a 404 Not Found error instead of returning None. ### Method Not applicable (this is a method of a Python class). ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters * **description** (_str_ or _None_) – A custom message to show on the error page. ### Return type _Any_ ``` -------------------------------- ### get_or_404 Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api Retrieves an object by its primary key. If the object is not found, it aborts with a 404 Not Found error. ```APIDOC ## get_or_404 ### Description Retrieves an object by its primary key. If the object is not found, it aborts with a 404 Not Found error instead of returning None. ### Method Not applicable (this is a method of a Python class). ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters * **ident** (_Any_) – The primary key to query. * **description** (_str_ or _None_) – A custom message to show on the error page. ### Return type _Any_ ``` -------------------------------- ### engines Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api Map of bind keys to Engine instances for the current application. The None key refers to the default engine. ```APIDOC ## engines Map of bind keys to `sqlalchemy.engine.Engine` instances for current application. The `None` key refers to the default engine, and is available as `engine`. To customize, set the `SQLALCHEMY_BINDS` config, and set defaults by passing the `engine_options` parameter to the extension. This requires that a Flask application context is active. Changelog Added in version 3.0. ``` -------------------------------- ### reflect Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api Loads table definitions from the database by calling `metadata.reflect()` for specified bind keys. This operation requires an active Flask application context. ```APIDOC ## reflect ### Description Load table definitions from the database by calling `metadata.reflect()` for all or some bind keys. This requires that a Flask application context is active. ### Parameters #### Path Parameters * **bind_key** (str | None | list[str | None]) - Optional - A bind key or list of keys to reflect the tables from. Defaults to all binds. ### Return type None ``` -------------------------------- ### Define SQLAlchemy Models Source: https://flask-sqlalchemy.readthedocs.io/en/stable/quickstart Define your database models by subclassing db.Model. Use Mapped and mapped_column for type hints and column definitions. ```python from sqlalchemy import Integer, String from sqlalchemy.orm import Mapped, mapped_column class User(db.Model): id: Mapped[int] = mapped_column(primary_key=True) username: Mapped[str] = mapped_column(unique=True) email: Mapped[str] ``` -------------------------------- ### metadatas Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api Map of bind keys to MetaData instances. The None key refers to the default metadata, available as metadata. ```APIDOC ## metadatas Map of bind keys to `sqlalchemy.schema.MetaData` instances. The `None` key refers to the default metadata, and is available as `metadata`. Customize the default metadata by passing the `metadata` parameter to the extension. This can be used to set a naming convention. When metadata for another bind key is created, it copies the default’s naming convention. Changelog Added in version 3.0. ``` -------------------------------- ### Define Table with a Specific Bind Key Source: https://flask-sqlalchemy.readthedocs.io/en/stable/binds Associate a table with a specific database bind by passing the `bind_key` keyword argument during its definition. ```python user_table = db.Table( "user", db.Column("id", db.Integer, primary_key=True), bind_key="auth", ) ``` -------------------------------- ### Define Model with a Specific Bind Key Source: https://flask-sqlalchemy.readthedocs.io/en/stable/binds Associate a model with a specific database bind by setting the `__bind_key__` class attribute. If not set, the default bind is used. ```python class User(db.Model): __bind_key__ = "auth" id = db.Column(db.Integer, primary_key=True) ``` -------------------------------- ### engine Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api The default Engine for the current application, used by session if the Model or Table being queried does not set a bind key. ```APIDOC ## engine The default `Engine` for the current application, used by `session` if the `Model` or `Table` being queried does not set a bind key. To customize, set the `SQLALCHEMY_ENGINE_OPTIONS` config, and set defaults by passing the `engine_options` parameter to the extension. This requires that a Flask application context is active. ``` -------------------------------- ### one_or_404 Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api Retrieves exactly one object from the query result. If no object or multiple objects are found, it aborts with a 404 Not Found error. ```APIDOC ## one_or_404 ### Description Retrieves exactly one object from the query result. If no object or multiple objects are found, it aborts with a 404 Not Found error instead of raising `NoResultFound` or `MultipleResultsFound`. ### Method Not applicable (this is a method of a Python class). ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters * **description** (_str_ or _None_) – A custom message to show on the error page. ### Return type _Any_ ``` -------------------------------- ### first_or_404 Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api Retrieves a single result from a statement or aborts with a 404 error if no result is found. It's similar to `Result.scalar()` but handles the not-found case by raising an HTTP 404 error. ```APIDOC ## first_or_404 ### Description Like `Result.scalar()`, but aborts with a `404 Not Found` error instead of returning `None`. ### Parameters #### Path Parameters * **statement** (Select) - Required - The `select` statement to execute. * **description** (str | None) - Optional - A custom message to show on the error page. ### Return type Any ``` -------------------------------- ### Reflect All Tables from Database Source: https://flask-sqlalchemy.readthedocs.io/en/stable/models Call `db.reflect()` within the application context to detect existing tables in the database and create corresponding table objects. This is useful when connecting to a pre-existing database schema. ```python with app.app_context(): db.reflect() ``` -------------------------------- ### drop_all Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api Drops database tables for specified bind keys by calling `metadata.drop_all()`. This operation requires an active Flask application context. ```APIDOC ## drop_all ### Description Drop tables by calling `metadata.drop_all()` for all or some bind keys. This requires that a Flask application context is active. ### Parameters #### Path Parameters * **bind_key** (str | None | list[str | None]) - Optional - A bind key or list of keys to drop the tables from. Defaults to all binds. ### Return type None ``` -------------------------------- ### Pytest Fixture for Application Context Source: https://flask-sqlalchemy.readthedocs.io/en/stable/contexts Provides a pytest fixture to manage application context for tests, ensuring it's pushed and yielded for the test duration. ```python 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() ``` -------------------------------- ### Table Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api A SQLAlchemy Table class that chooses a metadata automatically. The metadata argument is not required and is selected based on the bind_key argument. ```APIDOC ## Table A `sqlalchemy.schema.Table` class that chooses a metadata automatically. Unlike the base `Table`, the `metadata` argument is not required. If it is not given, it is selected based on the `bind_key` argument. Parameters: * **bind_key** – Used to select a different metadata. * **args** – Arguments passed to the base class. These are typically the table’s name, columns, and constraints. * **kwargs** – Arguments passed to the base class. Changelog Changed in version 3.0: This is a subclass of SQLAlchemy’s `Table` rather than a function. ``` -------------------------------- ### Custom Naming Convention for Constraints Source: https://flask-sqlalchemy.readthedocs.io/en/stable/models Optionally, construct the `SQLAlchemy` object with a custom `MetaData` object to specify a naming convention for constraints. This ensures consistent and predictable constraint names, which is beneficial for migrations. ```python 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" }) ``` -------------------------------- ### paginate Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api Applies pagination to a select statement, returning a `Pagination` object. It calculates the offset and limit based on the current page and items per page, with options to control error handling and count calculation. ```APIDOC ## paginate ### Description Apply an offset and limit to a select statment based on the current page and number of items per page, returning a `Pagination` object. The statement should select a model class, like `select(User)`. This applies `unique()` and `scalars()` modifiers to the result, so compound selects will not return the expected results. ### Parameters #### Path Parameters * **select** (Select) - Required - The `select` statement to paginate. * **page** (int | None) - Optional - The current page, used to calculate the offset. Defaults to the `page` query arg during a request, or 1 otherwise. * **per_page** (int | None) - Optional - The maximum number of items on a page, used to calculate the offset and limit. Defaults to the `per_page` query arg during a request, or 20 otherwise. * **max_per_page** (int | None) - Optional - The maximum allowed value for `per_page`, to limit a user-provided value. Use `None` for no limit. Defaults to 100. * **error_out** (bool) - Optional - Abort with a `404 Not Found` error if no items are returned and `page` is not 1, or if `page` or `per_page` is less than 1, or if either are not ints. Defaults to True. * **count** (bool) - Optional - Calculate the total number of values by issuing an extra count query. For very complex queries this may be inaccurate or slow, so it can be disabled and set manually if necessary. Defaults to True. ### Return type Pagination ``` -------------------------------- ### Model Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api The base class for SQLAlchemy declarative models. Users should subclass db.Model, not this directly, unless customizing the default db.Model. ```APIDOC ## Model ### Description The base class of the `SQLAlchemy.Model` declarative model class. To define models, subclass `db.Model`, not this. To customize `db.Model`, subclass this and pass it as `model_class` to `SQLAlchemy`. To customize `db.Model` at the metaclass level, pass an already created declarative model class as `model_class`. ### Attributes * **__bind_key__** Use this bind key to select a metadata and engine to associate with this model’s table. Ignored if `metadata` or `__table__` is set. If not given, uses the default key, `None`. * **__tablename__** The name of the table in the database. This is required by SQLAlchemy; however, Flask-SQLAlchemy will set it automatically if a model has a primary key defined. If the `__table__` or `__tablename__` is set explicitly, that will be used instead. * **query_class** Query class used by `query`. Defaults to `SQLAlchemy.Query`, which defaults to `Query`. alias of `Query` * **query** A SQLAlchemy query for a model. Equivalent to `db.session.query(Model)`. Can be customized per-model by overriding `query_class`. Warning The query interface is considered legacy in SQLAlchemy. Prefer using `session.execute(select())` instead. ``` -------------------------------- ### Model Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api A SQLAlchemy declarative model class. Subclass this to define database models. Table name is generated from class name if not set. ```APIDOC ## Model A SQLAlchemy declarative model class. Subclass this to define database models. If a model does not set `__tablename__`, it will be generated by converting the class name from `CamelCase` to `snake_case`. It will not be generated if the model looks like it uses single-table inheritance. If a model or parent class sets `__bind_key__`, it will use that metadata and database engine. Otherwise, it will use the default `metadata` and `engine`. This is ignored if the model sets `metadata` or `__table__`. For code using the SQLAlchemy 1.x API, customize this model by subclassing `Model` and passing the `model_class` parameter to the extension. A fully created declarative model class can be passed as well, to use a custom metaclass. For code using the SQLAlchemy 2.x API, customize this model by subclassing `sqlalchemy.orm.DeclarativeBase` or `sqlalchemy.orm.DeclarativeBaseNoMeta` and passing the `model_class` parameter to the extension. ``` -------------------------------- ### one_or_404 Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api Retrieves a single, unique result from a statement or aborts with a 404 error. This method is useful when you expect exactly one result and want to handle cases where zero or multiple results are found gracefully. ```APIDOC ## one_or_404 ### Description Like `Result.scalar_one()`, but aborts with a `404 Not Found` error instead of raising `NoResultFound` or `MultipleResultsFound`. ### Parameters #### Path Parameters * **statement** (Select) - Required - The `select` statement to execute. * **description** (str | None) - Optional - A custom message to show on the error page. ### Return type Any ``` -------------------------------- ### Session-Specific Query Class Customization Source: https://flask-sqlalchemy.readthedocs.io/en/stable/customizing Customize only `session.query` by passing the `query_cls` key to the `session_options` argument in the SQLAlchemy constructor. ```python db = SQLAlchemy(session_options={"query_cls": GetOrQuery}) ``` -------------------------------- ### Define a Many-to-Many Association Table Source: https://flask-sqlalchemy.readthedocs.io/en/stable/models Create instances of `db.Table` to define tables directly, often used for many-to-many relationships. The `metadata` argument is not required as it's inferred from the `bind_key` or default. ```python 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), ) ``` -------------------------------- ### metadata Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api The default metadata used by Model and Table if no bind key is set. ```APIDOC ## metadata The default metadata used by `Model` and `Table` if no bind key is set. ``` -------------------------------- ### Abstract Model for Timestamps Source: https://flask-sqlalchemy.readthedocs.io/en/stable/customizing Use an abstract model class to add common fields like creation and update timestamps to specific models. Set `__abstract__ = True` to prevent the abstract model from being mapped to a table. ```python from datetime import datetime, timezone from sqlalchemy.orm import Mapped, mapped_column class TimestampModel(db.Model): __abstract__ = True created: Mapped[datetime] = mapped_column(default=lambda: datetime.now(timezone.utc)) updated: Mapped[datetime] = mapped_column(default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc)) class Author(db.Model): id: Mapped[int] = mapped_column(primary_key=True) username: Mapped[str] = mapped_column(unique=True) class Post(TimestampModel): id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] ``` -------------------------------- ### Insert Data with Flask-SQLAlchemy Source: https://flask-sqlalchemy.readthedocs.io/en/stable/queries To insert new data, create a model instance, add it to the session, and commit the transaction. ```python user = User() db.session.add(user) db.session.commit() ``` -------------------------------- ### Execute Select Query with Flask-SQLAlchemy Source: https://flask-sqlalchemy.readthedocs.io/en/stable/queries Queries are executed using `db.session.execute()` with `select()`. Use `.scalar_one()` for a single result or `.scalars()` for multiple results. ```python 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() ``` -------------------------------- ### Custom Session Class for Horizontal Sharding Source: https://flask-sqlalchemy.readthedocs.io/en/stable/customizing Implement custom session logic, such as horizontal sharding, by defining a new class that inherits from `ShardedSession` and Flask-SQLAlchemy's `Session`. Pass this custom class via `session_options`. ```python from sqlalchemy.ext.horizontal_shard import ShardedSession from flask_sqlalchemy.session import Session class CustomSession(ShardedSession, Session): ... db = SQLAlchemy(session_options={"class_": CustomSession}) ``` -------------------------------- ### Enable Data Classes with Base Class Source: https://flask-sqlalchemy.readthedocs.io/en/stable/models To enable SQLAlchemy's native support for data classes, include `MappedAsDataclass` as an additional parent class when defining your base model class. ```python from sqlalchemy.orm import DeclarativeBase, MappedAsDataclass class Base(DeclarativeBase, MappedAsDataclass): pass ``` -------------------------------- ### Relationship-Specific Query Class Customization Source: https://flask-sqlalchemy.readthedocs.io/en/stable/customizing Customize the query class for a specific dynamic relationship by passing the `query_class` argument to the `db.relationship` function. ```python db.relationship(User, lazy="dynamic", query_class=GetOrQuery) ``` -------------------------------- ### Iterating through page numbers Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api Yields page numbers for a pagination widget, representing skipped pages with None. All parameters are keyword-only. ```python 1, 2, None, 5, 6, 7, 8, 9, 10, 11, None, 19, 20 ``` -------------------------------- ### Listen for Model Changes with Blinker Source: https://flask-sqlalchemy.readthedocs.io/en/stable/track-modifications Connect a listener function to the `models_committed` Blinker signal to receive a list of model changes after a commit. Ensure `SQLALCHEMY_TRACK_MODIFICATIONS` is enabled in your Flask app configuration. ```python 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) ``` -------------------------------- ### Mixin Class for Timestamps Source: https://flask-sqlalchemy.readthedocs.io/en/stable/customizing Alternatively, use a mixin class to provide shared behavior like timestamps. Inherit from the mixin class and `db.Model` when defining your models. ```python class TimestampMixin: created: Mapped[datetime] = mapped_column(default=lambda: datetime.now(timezone.utc)) updated: Mapped[datetime] = mapped_column(default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc)) class Post(TimestampMixin, db.Model): id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] ``` -------------------------------- ### session Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api A scoped session that creates instances of Session scoped to the current Flask application context. The session will be removed when the application context exits. ```APIDOC ## session A `sqlalchemy.orm.scoping.scoped_session` that creates instances of `Session` scoped to the current Flask application context. The session will be removed, returning the engine connection to the pool, when the application context exits. Customize this by passing `session_options` to the extension. This requires that a Flask application context is active. Changelog Changed in version 3.0: The session is scoped to the current app context. ``` -------------------------------- ### paginate Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api Paginates the query results, returning a Pagination object. It allows specifying page number, items per page, and error handling for invalid inputs. ```APIDOC ## paginate ### Description Applies an offset and limit to the query based on the current page and number of items per page, returning a `Pagination` object. ### Method Not applicable (this is a method of a Python class). ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters * **page** (_int_ or _None_) – The current page, used to calculate the offset. Defaults to the `page` query arg during a request, or 1 otherwise. * **per_page** (_int_ or _None_) – The maximum number of items on a page, used to calculate the offset and limit. Defaults to the `per_page` query arg during a request, or 20 otherwise. * **max_per_page** (_int_ or _None_) – The maximum allowed value for `per_page`, to limit a user-provided value. Use `None` for no limit. Defaults to 100. * **error_out** (_bool_) – Abort with a `404 Not Found` error if no items are returned and `page` is not 1, or if `page` or `per_page` is less than 1, or if either are not ints. * **count** (_bool_) – Calculate the total number of values by issuing an extra count query. For very complex queries this may be inaccurate or slow, so it can be disabled and set manually if necessary. ### Return type _Pagination_ ``` -------------------------------- ### Model-Specific Query Class Customization Source: https://flask-sqlalchemy.readthedocs.io/en/stable/customizing Customize the query interface for a specific model by setting the `query_class` attribute directly on the model class. ```python class User(db.Model): query_class = GetOrQuery ``` -------------------------------- ### relationship Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api Defines a relationship between SQLAlchemy models, applying the extension's `Query` class for dynamic relationships and backrefs. This enhances how relationships are handled within the Flask-SQLAlchemy context. ```APIDOC ## relationship ### Description A `sqlalchemy.orm.relationship()` that applies this extension’s `Query` class for dynamic relationships and backrefs. ### Parameters #### Path Parameters * **args** (Any) * **kwargs** (Any) ### Return type RelationshipProperty[Any] ``` -------------------------------- ### flask_sqlalchemy.record_queries.get_recorded_queries() Source: https://flask-sqlalchemy.readthedocs.io/en/stable/api Retrieves a list of recorded query information for the current session. Queries are logged if SQLALCHEMY_RECORD_QUERIES is enabled. Each query info object contains statement, parameters, timing, duration, and location. ```APIDOC ## get_recorded_queries() ### Description Get the list of recorded query information for the current session. Queries are recorded if the config `SQLALCHEMY_RECORD_QUERIES` is enabled. Each query info object has the following attributes: `statement` The string of SQL generated by SQLAlchemy with parameter placeholders. `parameters` The parameters sent with the SQL statement. `start_time` / `end_time` Timing info about when the query started execution and when the results where returned. Accuracy and value depends on the operating system. `duration` The time the query took in seconds. `location` A string description of where in your application code the query was executed. This may not be possible to calculate, and the format is not stable. ### Return Type list[__QueryInfo_] ```