1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
|
.. _quickstart:
Quick Start
===========
.. currentmodule:: flask_sqlalchemy
Flask-SQLAlchemy simplifies using SQLAlchemy by automatically handling creating, using,
and cleaning up the SQLAlchemy objects you'd normally work with. While it adds a few
useful features, it still works like SQLAlchemy.
This page will walk you through the basic use of Flask-SQLAlchemy. For full capabilities
and customization, see the rest of these docs, including the API docs for the
:class:`SQLAlchemy` object.
Check the SQLAlchemy Documentation
----------------------------------
Flask-SQLAlchemy is a wrapper around SQLAlchemy. You should follow the
`SQLAlchemy Tutorial`_ to learn about how to use it, and consult its documentation
for detailed information about its features. These docs show how to set up
Flask-SQLAlchemy itself, not how to use SQLAlchemy. Flask-SQLAlchemy sets up the
engine and scoped session automatically, so you can skip those
parts of the SQLAlchemy tutorial.
.. _SQLAlchemy Tutorial: https://docs.sqlalchemy.org/en/20/tutorial/index.html
This guide assumes you are using SQLAlchemy 2.x, which has a new API for defining models
and better support for Python type hints and data classes. If you are using SQLAlchemy 1.x,
see :doc:`legacy-quickstart`.
Installation
------------
Flask-SQLAlchemy is available on `PyPI`_ and can be installed with various Python tools.
For example, to install or update the latest version using pip:
.. code-block:: text
$ pip install -U Flask-SQLAlchemy
.. _PyPI: https://pypi.org/project/Flask-SQLAlchemy/
Initialize the Extension
------------------------
First create the ``db`` object using the ``SQLAlchemy`` constructor.
Pass a subclass of either `DeclarativeBase`_ or `DeclarativeBaseNoMeta`_
to the constructor.
.. code-block:: python
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.orm import DeclarativeBase
class Base(DeclarativeBase):
pass
db = SQLAlchemy(model_class=Base)
Learn more about customizing the base model class in :doc:`models`.
.. _DeclarativeBase: https://docs.sqlalchemy.org/en/20/orm/mapping_api.html#sqlalchemy.orm.DeclarativeBase
.. _DeclarativeBaseNoMeta: https://docs.sqlalchemy.org/en/20/orm/mapping_api.html#sqlalchemy.orm.DeclarativeBaseNoMeta
About the ``SQLAlchemy`` object
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Once constructed, the ``db`` object gives you access to the :attr:`db.Model <.SQLAlchemy.Model>` class to
define models, and the :attr:`db.session <.SQLAlchemy.session>` to execute queries.
The :class:`SQLAlchemy` object also takes additional arguments to customize the
objects it manages.
Configure the Extension
-----------------------
The next step is to connect the extension to your Flask app.
The only required Flask app config is the :data:`.SQLALCHEMY_DATABASE_URI` key. That
is a connection string that tells SQLAlchemy what database to connect to.
Create your Flask application object, load any config, and then initialize the
:class:`SQLAlchemy` extension class with the application by calling
:meth:`db.init_app <.SQLAlchemy.init_app>`. This example connects to a SQLite database,
which is stored in the app's instance folder.
.. code-block:: python
# 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)
See :doc:`config` for an explanation of connections strings and what other configuration
keys are used.
Define Models
-------------
Subclass ``db.Model`` to define a model class.
The model will generate a table name by converting the ``CamelCase`` class name to
``snake_case``.
.. code-block:: python
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)
See :doc:`models` for more information about defining and creating models and tables.
Create the Tables
-----------------
After all models and tables are defined, call :meth:`.SQLAlchemy.create_all` to create
the table schema in the database. This requires an application context. Since you're not
in a request at this point, create one manually.
.. code-block:: python
with app.app_context():
db.create_all()
If you define models in other modules, you must import them before calling
``create_all``, otherwise SQLAlchemy will not know about them.
``create_all`` does not update tables if they are already in the database. If you change
a model's columns, use a migration library like `Alembic`_ with `Flask-Alembic`_ or
`Flask-Migrate`_ to generate migrations that update the database schema.
.. _Alembic: https://alembic.sqlalchemy.org/
.. _Flask-Alembic: https://flask-alembic.readthedocs.io/
.. _Flask-Migrate: https://flask-migrate.readthedocs.io/
Query the Data
--------------
Within a Flask view or CLI command, you can use ``db.session`` to execute queries and
modify model data.
SQLAlchemy automatically defines an ``__init__`` method for each model that assigns any
keyword arguments to corresponding database columns and other attributes.
``db.session.add(obj)`` adds an object to the session, to be inserted. Modifying an
object's attributes updates the object. ``db.session.delete(obj)`` deletes an object.
Remember to call ``db.session.commit()`` after modifying, adding, or deleting any data.
``db.session.execute(db.select(...))`` constructs a query to select data from the
database. Building queries is the main feature of SQLAlchemy, so you'll want to read its
`tutorial on select`_ to learn all about it. You'll usually use the ``Result.scalars()``
method to get a list of results, or the ``Result.scalar()`` method to get a single
result.
.. _tutorial on select: https://docs.sqlalchemy.org/tutorial/data_select.html
.. code-block:: python
@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/<int:id>")
def user_detail(id):
user = db.get_or_404(User, id)
return render_template("user/detail.html", user=user)
@app.route("/user/<int:id>/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)
You may see uses of ``Model.query`` to build queries. This is an older interface for
queries that is considered legacy in SQLAlchemy. Prefer using
``db.session.execute(db.select(...))`` instead.
See :doc:`queries` for more information about queries.
What to Remember
----------------
For the most part, you should use SQLAlchemy as usual. The :class:`SQLAlchemy` extension
instance creates, configures, and gives access to the following things:
- :attr:`.SQLAlchemy.Model` declarative model base class. It sets the table
name automatically instead of needing ``__tablename__``.
- :attr:`.SQLAlchemy.session` is a session that is scoped to the current
Flask application context. It is cleaned up after every request.
- :attr:`.SQLAlchemy.metadata` and :attr:`.SQLAlchemy.metadatas` gives access to each
metadata defined in the config.
- :attr:`.SQLAlchemy.engine` and :attr:`.SQLAlchemy.engines` gives access to each
engine defined in the config.
- :meth:`.SQLAlchemy.create_all` creates all tables.
- You must be in an active Flask application context to execute queries and to access
the session and engine.
|