File: quickstart.rst

package info (click to toggle)
flask-sqlalchemy 3.1.1-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 832 kB
  • sloc: python: 2,909; makefile: 27; sh: 14
file content (230 lines) | stat: -rw-r--r-- 8,398 bytes parent folder | download
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.