[pre-commit.ci lite] apply automatic fixes

This commit is contained in:
pre-commit-ci-lite[bot] 2025-04-11 03:04:22 +00:00 committed by GitHub
parent b3ae3117f9
commit 3d83d8138c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
102 changed files with 26790 additions and 26749 deletions

View file

@ -5,7 +5,7 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Large Applications as Packages &#8212; Flask Documentation (3.2.x)</title>
<title>SQLAlchemy in Flask &#8212; Flask Documentation (3.2.x)</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=6625fa76" />
<link rel="stylesheet" type="text/css" href="../_static/flask.css?v=b87c8d14" />
<script src="../_static/documentation_options.js?v=56528222"></script>
@ -15,8 +15,8 @@
<link rel="icon" href="../_static/shortcut-icon.png"/>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Application Factories" href="appfactories.html" />
<link rel="prev" title="Patterns for Flask" href="index.html" />
<link rel="next" title="Uploading Files" href="fileuploads.html" />
<link rel="prev" title="Using SQLite 3 with Flask" href="sqlite3.html" />
</head><body>
<div class="related" role="navigation" aria-label="Related">
<h3>Navigation</h3>
@ -28,144 +28,217 @@
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="appfactories.html" title="Application Factories"
<a href="fileuploads.html" title="Uploading Files"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="index.html" title="Patterns for Flask"
<a href="sqlite3.html" title="Using SQLite 3 with Flask"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Flask Documentation (3.2.x)</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Patterns for Flask</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Large Applications as Packages</a></li>
<li class="nav-item nav-item-this"><a href="">SQLAlchemy in Flask</a></li>
</ul>
</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="large-applications-as-packages">
<h1>Large Applications as Packages<a class="headerlink" href="#large-applications-as-packages" title="Link to this heading"></a></h1>
<p>Imagine a simple flask application structure that looks like this:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">/</span><span class="n">yourapplication</span>
<span class="n">yourapplication</span><span class="o">.</span><span class="n">py</span>
<span class="o">/</span><span class="n">static</span>
<span class="n">style</span><span class="o">.</span><span class="n">css</span>
<span class="o">/</span><span class="n">templates</span>
<span class="n">layout</span><span class="o">.</span><span class="n">html</span>
<span class="n">index</span><span class="o">.</span><span class="n">html</span>
<span class="n">login</span><span class="o">.</span><span class="n">html</span>
<span class="o">...</span>
</pre></div>
</div>
<p>While this is fine for small applications, for larger applications
its a good idea to use a package instead of a module.
The <a class="reference internal" href="../tutorial/index.html"><span class="doc">Tutorial</span></a> is structured to use the package pattern,
see the <a class="reference external" href="https://github.com/pallets/flask/tree/main/examples/tutorial">example code</a>.</p>
<section id="simple-packages">
<h2>Simple Packages<a class="headerlink" href="#simple-packages" title="Link to this heading"></a></h2>
<p>To convert that into a larger one, just create a new folder
<code class="file docutils literal notranslate"><span class="pre">yourapplication</span></code> inside the existing one and move everything below it.
Then rename <code class="file docutils literal notranslate"><span class="pre">yourapplication.py</span></code> to <code class="file docutils literal notranslate"><span class="pre">__init__.py</span></code>. (Make sure to delete
all <code class="docutils literal notranslate"><span class="pre">.pyc</span></code> files first, otherwise things would most likely break)</p>
<p>You should then end up with something like that:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">/</span><span class="n">yourapplication</span>
<span class="o">/</span><span class="n">yourapplication</span>
<span class="fm">__init__</span><span class="o">.</span><span class="n">py</span>
<span class="o">/</span><span class="n">static</span>
<span class="n">style</span><span class="o">.</span><span class="n">css</span>
<span class="o">/</span><span class="n">templates</span>
<span class="n">layout</span><span class="o">.</span><span class="n">html</span>
<span class="n">index</span><span class="o">.</span><span class="n">html</span>
<span class="n">login</span><span class="o">.</span><span class="n">html</span>
<span class="o">...</span>
</pre></div>
</div>
<p>But how do you run your application now? The naive <code class="docutils literal notranslate"><span class="pre">python</span>
<span class="pre">yourapplication/__init__.py</span></code> will not work. Lets just say that Python
does not want modules in packages to be the startup file. But that is not
a big problem, just add a new file called <code class="file docutils literal notranslate"><span class="pre">pyproject.toml</span></code> next to the inner
<code class="file docutils literal notranslate"><span class="pre">yourapplication</span></code> folder with the following contents:</p>
<div class="highlight-toml notranslate"><div class="highlight"><pre><span></span><span class="k">[project]</span>
<span class="n">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;yourapplication&quot;</span>
<span class="n">dependencies</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="s2">&quot;flask&quot;</span><span class="p">,</span>
<span class="p">]</span>
<span class="k">[build-system]</span>
<span class="n">requires</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;flit_core&lt;4&quot;</span><span class="p">]</span>
<span class="n">build-backend</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;flit_core.buildapi&quot;</span>
</pre></div>
</div>
<p>Install your application so it is importable:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>$ pip install -e .
</pre></div>
</div>
<p>To use the <code class="docutils literal notranslate"><span class="pre">flask</span></code> command and run your application you need to set
the <code class="docutils literal notranslate"><span class="pre">--app</span></code> option that tells Flask where to find the application
instance:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>$ flask --app yourapplication run
</pre></div>
</div>
<p>What did we gain from this? Now we can restructure the application a bit
into multiple modules. The only thing you have to remember is the
following quick checklist:</p>
<ol class="arabic simple">
<li><p>the <code class="code docutils literal notranslate"><span class="pre">Flask</span></code> application object creation has to be in the
<code class="file docutils literal notranslate"><span class="pre">__init__.py</span></code> file. That way each module can import it safely and the
<code class="code docutils literal notranslate"><span class="pre">__name__</span></code> variable will resolve to the correct package.</p></li>
<li><p>all the view functions (the ones with a <a class="reference internal" href="../api.html#flask.Flask.route" title="flask.Flask.route"><code class="xref py py-meth docutils literal notranslate"><span class="pre">route()</span></code></a>
decorator on top) have to be imported in the <code class="file docutils literal notranslate"><span class="pre">__init__.py</span></code> file.
Not the object itself, but the module it is in. Import the view module
<strong>after the application object is created</strong>.</p></li>
</ol>
<p>Heres an example <code class="file docutils literal notranslate"><span class="pre">__init__.py</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">flask</span><span class="w"> </span><span class="kn">import</span> <span class="n">Flask</span>
<span class="n">app</span> <span class="o">=</span> <span class="n">Flask</span><span class="p">(</span><span class="vm">__name__</span><span class="p">)</span>
<section id="sqlalchemy-in-flask">
<h1>SQLAlchemy in Flask<a class="headerlink" href="#sqlalchemy-in-flask" title="Link to this heading"></a></h1>
<p>Many people prefer <a class="reference external" href="https://www.sqlalchemy.org/">SQLAlchemy</a> for database access. In this case its
encouraged to use a package instead of a module for your flask application
and drop the models into a separate module (<a class="reference internal" href="packages.html"><span class="doc">Large Applications as Packages</span></a>). While that
is not necessary, it makes a lot of sense.</p>
<p>There are four very common ways to use SQLAlchemy. I will outline each
of them here:</p>
<section id="flask-sqlalchemy-extension">
<h2>Flask-SQLAlchemy Extension<a class="headerlink" href="#flask-sqlalchemy-extension" title="Link to this heading"></a></h2>
<p>Because SQLAlchemy is a common database abstraction layer and object
relational mapper that requires a little bit of configuration effort,
there is a Flask extension that handles that for you. This is recommended
if you want to get started quickly.</p>
<p>You can download <a class="reference external" href="https://flask-sqlalchemy.palletsprojects.com/">Flask-SQLAlchemy</a> from <a class="reference external" href="https://pypi.org/project/Flask-SQLAlchemy/">PyPI</a>.</p>
</section>
<section id="declarative">
<h2>Declarative<a class="headerlink" href="#declarative" title="Link to this heading"></a></h2>
<p>The declarative extension in SQLAlchemy is the most recent method of using
SQLAlchemy. It allows you to define tables and models in one go, similar
to how Django works. In addition to the following text I recommend the
official documentation on the <a class="reference external" href="https://docs.sqlalchemy.org/en/latest/orm/extensions/declarative/">declarative</a> extension.</p>
<p>Heres the example <code class="file docutils literal notranslate"><span class="pre">database.py</span></code> module for your application:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">sqlalchemy</span><span class="w"> </span><span class="kn">import</span> <span class="n">create_engine</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">sqlalchemy.orm</span><span class="w"> </span><span class="kn">import</span> <span class="n">scoped_session</span><span class="p">,</span> <span class="n">sessionmaker</span><span class="p">,</span> <span class="n">declarative_base</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">yourapplication.views</span>
</pre></div>
</div>
<p>And this is what <code class="file docutils literal notranslate"><span class="pre">views.py</span></code> would look like:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">yourapplication</span><span class="w"> </span><span class="kn">import</span> <span class="n">app</span>
<span class="n">engine</span> <span class="o">=</span> <span class="n">create_engine</span><span class="p">(</span><span class="s1">&#39;sqlite:////tmp/test.db&#39;</span><span class="p">)</span>
<span class="n">db_session</span> <span class="o">=</span> <span class="n">scoped_session</span><span class="p">(</span><span class="n">sessionmaker</span><span class="p">(</span><span class="n">autocommit</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">autoflush</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">bind</span><span class="o">=</span><span class="n">engine</span><span class="p">))</span>
<span class="n">Base</span> <span class="o">=</span> <span class="n">declarative_base</span><span class="p">()</span>
<span class="n">Base</span><span class="o">.</span><span class="n">query</span> <span class="o">=</span> <span class="n">db_session</span><span class="o">.</span><span class="n">query_property</span><span class="p">()</span>
<span class="nd">@app</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">index</span><span class="p">():</span>
<span class="k">return</span> <span class="s1">&#39;Hello World!&#39;</span>
<span class="k">def</span><span class="w"> </span><span class="nf">init_db</span><span class="p">():</span>
<span class="c1"># import all modules here that might define models so that</span>
<span class="c1"># they will be registered properly on the metadata. Otherwise</span>
<span class="c1"># you will have to import them first before calling init_db()</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">yourapplication.models</span>
<span class="n">Base</span><span class="o">.</span><span class="n">metadata</span><span class="o">.</span><span class="n">create_all</span><span class="p">(</span><span class="n">bind</span><span class="o">=</span><span class="n">engine</span><span class="p">)</span>
</pre></div>
</div>
<p>You should then end up with something like that:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">/</span><span class="n">yourapplication</span>
<span class="n">pyproject</span><span class="o">.</span><span class="n">toml</span>
<span class="o">/</span><span class="n">yourapplication</span>
<span class="fm">__init__</span><span class="o">.</span><span class="n">py</span>
<span class="n">views</span><span class="o">.</span><span class="n">py</span>
<span class="o">/</span><span class="n">static</span>
<span class="n">style</span><span class="o">.</span><span class="n">css</span>
<span class="o">/</span><span class="n">templates</span>
<span class="n">layout</span><span class="o">.</span><span class="n">html</span>
<span class="n">index</span><span class="o">.</span><span class="n">html</span>
<span class="n">login</span><span class="o">.</span><span class="n">html</span>
<span class="o">...</span>
<p>To define your models, just subclass the <code class="code docutils literal notranslate"><span class="pre">Base</span></code> class that was created by
the code above. If you are wondering why we dont have to care about
threads here (like we did in the SQLite3 example above with the
<a class="reference internal" href="../api.html#flask.g" title="flask.g"><code class="xref py py-data docutils literal notranslate"><span class="pre">g</span></code></a> object): thats because SQLAlchemy does that for us
already with the <a class="reference external" href="https://docs.sqlalchemy.org/en/20/orm/contextual.html#sqlalchemy.orm.scoped_session" title="(in SQLAlchemy v2.0)"><code class="xref py py-class docutils literal notranslate"><span class="pre">scoped_session</span></code></a>.</p>
<p>To use SQLAlchemy in a declarative way with your application, you just
have to put the following code into your application module. Flask will
automatically remove database sessions at the end of the request or
when the application shuts down:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">yourapplication.database</span><span class="w"> </span><span class="kn">import</span> <span class="n">db_session</span>
<span class="nd">@app</span><span class="o">.</span><span class="n">teardown_appcontext</span>
<span class="k">def</span><span class="w"> </span><span class="nf">shutdown_session</span><span class="p">(</span><span class="n">exception</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="n">db_session</span><span class="o">.</span><span class="n">remove</span><span class="p">()</span>
</pre></div>
</div>
<div class="admonition-circular-imports admonition">
<p class="admonition-title">Circular Imports</p>
<p>Every Python programmer hates them, and yet we just added some:
circular imports (Thats when two modules depend on each other. In this
case <code class="file docutils literal notranslate"><span class="pre">views.py</span></code> depends on <code class="file docutils literal notranslate"><span class="pre">__init__.py</span></code>). Be advised that this is a
bad idea in general but here it is actually fine. The reason for this is
that we are not actually using the views in <code class="file docutils literal notranslate"><span class="pre">__init__.py</span></code> and just
ensuring the module is imported and we are doing that at the bottom of
the file.</p>
<p>Here is an example model (put this into <code class="file docutils literal notranslate"><span class="pre">models.py</span></code>, e.g.):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">sqlalchemy</span><span class="w"> </span><span class="kn">import</span> <span class="n">Column</span><span class="p">,</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">String</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">yourapplication.database</span><span class="w"> </span><span class="kn">import</span> <span class="n">Base</span>
<span class="k">class</span><span class="w"> </span><span class="nc">User</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
<span class="n">__tablename__</span> <span class="o">=</span> <span class="s1">&#39;users&#39;</span>
<span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">name</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">(</span><span class="mi">50</span><span class="p">),</span> <span class="n">unique</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">email</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">(</span><span class="mi">120</span><span class="p">),</span> <span class="n">unique</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">email</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
<span class="bp">self</span><span class="o">.</span><span class="n">email</span> <span class="o">=</span> <span class="n">email</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="sa">f</span><span class="s1">&#39;&lt;User </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="si">!r}</span><span class="s1">&gt;&#39;</span>
</pre></div>
</div>
<p>To create the database you can use the <code class="code docutils literal notranslate"><span class="pre">init_db</span></code> function:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span><span class="w"> </span><span class="nn">yourapplication.database</span><span class="w"> </span><span class="kn">import</span> <span class="n">init_db</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">init_db</span><span class="p">()</span>
</pre></div>
</div>
<p>You can insert entries into the database like this:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span><span class="w"> </span><span class="nn">yourapplication.database</span><span class="w"> </span><span class="kn">import</span> <span class="n">db_session</span>
<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span><span class="w"> </span><span class="nn">yourapplication.models</span><span class="w"> </span><span class="kn">import</span> <span class="n">User</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">u</span> <span class="o">=</span> <span class="n">User</span><span class="p">(</span><span class="s1">&#39;admin&#39;</span><span class="p">,</span> <span class="s1">&#39;admin@localhost&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">db_session</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">u</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">db_session</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span>
</pre></div>
</div>
<p>Querying is simple as well:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">User</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="go">[&lt;User &#39;admin&#39;&gt;]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">User</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">User</span><span class="o">.</span><span class="n">name</span> <span class="o">==</span> <span class="s1">&#39;admin&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">first</span><span class="p">()</span>
<span class="go">&lt;User &#39;admin&#39;&gt;</span>
</pre></div>
</div>
</section>
<section id="working-with-blueprints">
<h2>Working with Blueprints<a class="headerlink" href="#working-with-blueprints" title="Link to this heading"></a></h2>
<p>If you have larger applications its recommended to divide them into
smaller groups where each group is implemented with the help of a
blueprint. For a gentle introduction into this topic refer to the
<a class="reference internal" href="../blueprints.html"><span class="doc">Modular Applications with Blueprints</span></a> chapter of the documentation.</p>
<section id="manual-object-relational-mapping">
<h2>Manual Object Relational Mapping<a class="headerlink" href="#manual-object-relational-mapping" title="Link to this heading"></a></h2>
<p>Manual object relational mapping has a few upsides and a few downsides
versus the declarative approach from above. The main difference is that
you define tables and classes separately and map them together. Its more
flexible but a little more to type. In general it works like the
declarative approach, so make sure to also split up your application into
multiple modules in a package.</p>
<p>Here is an example <code class="file docutils literal notranslate"><span class="pre">database.py</span></code> module for your application:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">sqlalchemy</span><span class="w"> </span><span class="kn">import</span> <span class="n">create_engine</span><span class="p">,</span> <span class="n">MetaData</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">sqlalchemy.orm</span><span class="w"> </span><span class="kn">import</span> <span class="n">scoped_session</span><span class="p">,</span> <span class="n">sessionmaker</span>
<span class="n">engine</span> <span class="o">=</span> <span class="n">create_engine</span><span class="p">(</span><span class="s1">&#39;sqlite:////tmp/test.db&#39;</span><span class="p">)</span>
<span class="n">metadata</span> <span class="o">=</span> <span class="n">MetaData</span><span class="p">()</span>
<span class="n">db_session</span> <span class="o">=</span> <span class="n">scoped_session</span><span class="p">(</span><span class="n">sessionmaker</span><span class="p">(</span><span class="n">autocommit</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">autoflush</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">bind</span><span class="o">=</span><span class="n">engine</span><span class="p">))</span>
<span class="k">def</span><span class="w"> </span><span class="nf">init_db</span><span class="p">():</span>
<span class="n">metadata</span><span class="o">.</span><span class="n">create_all</span><span class="p">(</span><span class="n">bind</span><span class="o">=</span><span class="n">engine</span><span class="p">)</span>
</pre></div>
</div>
<p>As in the declarative approach, you need to close the session after
each request or application context shutdown. Put this into your
application module:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">yourapplication.database</span><span class="w"> </span><span class="kn">import</span> <span class="n">db_session</span>
<span class="nd">@app</span><span class="o">.</span><span class="n">teardown_appcontext</span>
<span class="k">def</span><span class="w"> </span><span class="nf">shutdown_session</span><span class="p">(</span><span class="n">exception</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="n">db_session</span><span class="o">.</span><span class="n">remove</span><span class="p">()</span>
</pre></div>
</div>
<p>Here is an example table and model (put this into <code class="file docutils literal notranslate"><span class="pre">models.py</span></code>):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">sqlalchemy</span><span class="w"> </span><span class="kn">import</span> <span class="n">Table</span><span class="p">,</span> <span class="n">Column</span><span class="p">,</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">String</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">sqlalchemy.orm</span><span class="w"> </span><span class="kn">import</span> <span class="n">mapper</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">yourapplication.database</span><span class="w"> </span><span class="kn">import</span> <span class="n">metadata</span><span class="p">,</span> <span class="n">db_session</span>
<span class="k">class</span><span class="w"> </span><span class="nc">User</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="n">query</span> <span class="o">=</span> <span class="n">db_session</span><span class="o">.</span><span class="n">query_property</span><span class="p">()</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">email</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
<span class="bp">self</span><span class="o">.</span><span class="n">email</span> <span class="o">=</span> <span class="n">email</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="sa">f</span><span class="s1">&#39;&lt;User </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="si">!r}</span><span class="s1">&gt;&#39;</span>
<span class="n">users</span> <span class="o">=</span> <span class="n">Table</span><span class="p">(</span><span class="s1">&#39;users&#39;</span><span class="p">,</span> <span class="n">metadata</span><span class="p">,</span>
<span class="n">Column</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">,</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="kc">True</span><span class="p">),</span>
<span class="n">Column</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">,</span> <span class="n">String</span><span class="p">(</span><span class="mi">50</span><span class="p">),</span> <span class="n">unique</span><span class="o">=</span><span class="kc">True</span><span class="p">),</span>
<span class="n">Column</span><span class="p">(</span><span class="s1">&#39;email&#39;</span><span class="p">,</span> <span class="n">String</span><span class="p">(</span><span class="mi">120</span><span class="p">),</span> <span class="n">unique</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="p">)</span>
<span class="n">mapper</span><span class="p">(</span><span class="n">User</span><span class="p">,</span> <span class="n">users</span><span class="p">)</span>
</pre></div>
</div>
<p>Querying and inserting works exactly the same as in the example above.</p>
</section>
<section id="sql-abstraction-layer">
<h2>SQL Abstraction Layer<a class="headerlink" href="#sql-abstraction-layer" title="Link to this heading"></a></h2>
<p>If you just want to use the database system (and SQL) abstraction layer
you basically only need the engine:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">sqlalchemy</span><span class="w"> </span><span class="kn">import</span> <span class="n">create_engine</span><span class="p">,</span> <span class="n">MetaData</span><span class="p">,</span> <span class="n">Table</span>
<span class="n">engine</span> <span class="o">=</span> <span class="n">create_engine</span><span class="p">(</span><span class="s1">&#39;sqlite:////tmp/test.db&#39;</span><span class="p">)</span>
<span class="n">metadata</span> <span class="o">=</span> <span class="n">MetaData</span><span class="p">(</span><span class="n">bind</span><span class="o">=</span><span class="n">engine</span><span class="p">)</span>
</pre></div>
</div>
<p>Then you can either declare the tables in your code like in the examples
above, or automatically load them:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">sqlalchemy</span><span class="w"> </span><span class="kn">import</span> <span class="n">Table</span>
<span class="n">users</span> <span class="o">=</span> <span class="n">Table</span><span class="p">(</span><span class="s1">&#39;users&#39;</span><span class="p">,</span> <span class="n">metadata</span><span class="p">,</span> <span class="n">autoload</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</pre></div>
</div>
<p>To insert data you can use the <code class="code docutils literal notranslate"><span class="pre">insert</span></code> method. We have to get a
connection first so that we can use a transaction:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">con</span> <span class="o">=</span> <span class="n">engine</span><span class="o">.</span><span class="n">connect</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">con</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">users</span><span class="o">.</span><span class="n">insert</span><span class="p">(),</span> <span class="n">name</span><span class="o">=</span><span class="s1">&#39;admin&#39;</span><span class="p">,</span> <span class="n">email</span><span class="o">=</span><span class="s1">&#39;admin@localhost&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>SQLAlchemy will automatically commit for us.</p>
<p>To query your database, you use the engine directly or use a connection:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">users</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="n">users</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">id</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">execute</span><span class="p">()</span><span class="o">.</span><span class="n">first</span><span class="p">()</span>
<span class="go">(1, &#39;admin&#39;, &#39;admin@localhost&#39;)</span>
</pre></div>
</div>
<p>These results are also dict-like tuples:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">r</span> <span class="o">=</span> <span class="n">users</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="n">users</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">id</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">execute</span><span class="p">()</span><span class="o">.</span><span class="n">first</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">r</span><span class="p">[</span><span class="s1">&#39;name&#39;</span><span class="p">]</span>
<span class="go">&#39;admin&#39;</span>
</pre></div>
</div>
<p>You can also pass strings of SQL statements to the
<code class="xref py py-meth docutils literal notranslate"><span class="pre">execute()</span></code> method:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">engine</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s1">&#39;select * from users where id = :1&#39;</span><span class="p">,</span> <span class="p">[</span><span class="mi">1</span><span class="p">])</span><span class="o">.</span><span class="n">first</span><span class="p">()</span>
<span class="go">(1, &#39;admin&#39;, &#39;admin@localhost&#39;)</span>
</pre></div>
</div>
<p>For more information about SQLAlchemy, head over to the
<a class="reference external" href="https://www.sqlalchemy.org/">website</a>.</p>
</section>
</section>
@ -177,18 +250,20 @@ blueprint. For a gentle introduction into this topic refer to the
<span id="sidebar-top"></span>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/flask-vertical.png" alt="Logo of Flask"/>
</a></p>
<h3>Contents</h3>
<ul>
<li><a class="reference internal" href="#">Large Applications as Packages</a><ul>
<li><a class="reference internal" href="#simple-packages">Simple Packages</a></li>
<li><a class="reference internal" href="#working-with-blueprints">Working with Blueprints</a></li>
<li><a class="reference internal" href="#">SQLAlchemy in Flask</a><ul>
<li><a class="reference internal" href="#flask-sqlalchemy-extension">Flask-SQLAlchemy Extension</a></li>
<li><a class="reference internal" href="#declarative">Declarative</a></li>
<li><a class="reference internal" href="#manual-object-relational-mapping">Manual Object Relational Mapping</a></li>
<li><a class="reference internal" href="#sql-abstraction-layer">SQL Abstraction Layer</a></li>
</ul>
</li>
</ul>
@ -198,8 +273,8 @@ blueprint. For a gentle introduction into this topic refer to the
<ul>
<li><a href="index.html">Patterns for Flask</a>
<ul>
<li>Previous: <a href="index.html" title="previous chapter">Patterns for Flask</a>
<li>Next: <a href="appfactories.html" title="next chapter">Application Factories</a></ul>
<li>Previous: <a href="sqlite3.html" title="previous chapter">Using SQLite 3 with Flask</a>
<li>Next: <a href="fileuploads.html" title="next chapter">Uploading Files</a></ul>
</li>
</ul>
</li>
@ -223,4 +298,4 @@ blueprint. For a gentle introduction into this topic refer to the
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.1.3.
</div>
</body>
</html>
</html>