Flask 烧瓶,管理数据库连接(无ORM)

Flask 烧瓶,管理数据库连接(无ORM),flask,Flask,总的来说,我是Flask和web编程的新手,所以我试图理解框架的上下文和db操作的原理。 现在,我想了解如何在没有Sql Alchemy和其他ORM的情况下管理DB连接,只使用普通Sql 下面是SQLITE3DB的简单示例。 我的测试项目的结构: . ├── application │   ├── __init__.py │   ├── routes.py │   └── templates │   ├── base.html │   ├── index.html ├── con

总的来说,我是Flask和web编程的新手,所以我试图理解框架的上下文和db操作的原理。 现在,我想了解如何在没有Sql Alchemy和其他ORM的情况下管理DB连接,只使用普通Sql

下面是SQLITE3DB的简单示例。 我的测试项目的结构:

.
├── application
│   ├── __init__.py
│   ├── routes.py
│   └── templates
│       ├── base.html
│       ├── index.html
├── config.py
├── requirements.txt
├── run.py
└── test.db
init.py

从烧瓶进口烧瓶,g 从配置导入配置 导入sqlite3 app=烧瓶名称__ app.config.from_objectConfig def get_db: db=getattrg,“_数据库”,无 如果db为无: db=g._database=sqlite3.connect'test.db' 返回数据库 @app.teardown_appcontext def关闭_连接异常: db=getattrg,“_数据库”,无 如果db不是无: db.close 从应用程序导入路由 routes.py

-*-编码:utf-8-*- 从flask导入渲染_模板,重定向 从应用程序导入应用程序,获取_db 导入sqlite3 @应用程序路径“/” def索引: cur=get_db.cursor 当前执行“从用户选择* 选择=cur.fetchall 返回render_模板'index.html',title='dbselectest',posts=select 我从Flask framework的官方网站复制了get_db和close_connection函数,但我不清楚它是如何工作的,如果我只使用def get_db的简单代码而不使用g,那么会有什么区别:

con = sqlite3.connect("catalog.db")
cur = con.cursor() 
cur.close()    
con.close() 
很明显,查询完成后会关闭连接,如下所示:

con = sqlite3.connect("catalog.db")
cur = con.cursor() 
cur.close()    
con.close() 
我只是想通过使用g来了解在这种情况下应用程序和请求上下文是如何工作的。 主要的问题是我不明白在这种情况下什么是请求

我对这个案子的错误理解是:

因此,在init.py中,我们创建了全局变量g,该变量位于应用程序上下文中,并且对于请求上下文中的每个tread都应该是可访问的。 在routes.py中,我们从具有根route/的客户机获得查询,因此在该时刻创建了请求上下文,在该应用程序上下文之后也创建了请求上下文。 据我所知,get_db可以从我们的请求上下文访问,我们可以连接到db,并在当前tread中的所有函数中使用该g值?近距离连接怎么样?由于decorator teardown_appcontext,在应用程序上下文失败或结束后,连接必须关闭?它能在我的代码中工作吗


那么,有没有人能提供一个使用纯sql和单独连接函数的正确例子呢?

就代码而言,Flask应用程序和请求上下文的行为类似于全局变量,但实际上它们是代理,每次应用程序接收到新的web请求时,都会包含不同的值。请求上下文包含特定于该特定web请求的数据,例如表单数据、远程ip地址、http头等

每次收到web请求时,都会在调用view函数之前创建新的应用程序和请求上下文,然后在返回响应并完成web请求处理后销毁这些上下文。g代理与应用程序上下文一起存储,用于存储特定web请求的生命周期内的变量。这用于在flask调用的函数之间传递信息,这些函数是事件和信号的结果

在您的代码中,您使用一个decorator来注册函数close_connection和teardown_appcontext事件,从而保证在完成每个web请求的处理后调用该函数。还有许多其他事件可以挂接在view函数之前或之后执行,以提供请求或响应的预处理和后处理。g代理仅用于存储在view函数中创建的数据库连接,并使其可用于close_connection函数,在该函数中,它保证是关闭的。这可以防止在应用程序代码中发生错误时数据库连接保持打开状态

如下所示,该模式用于完成与使用上下文管理器或try(除了finally块)关闭函数中的数据库连接完全相同的任务。此模式通常与ORM一起使用,以隐藏数据库连接的底层管理并减少样板代码。在不使用事件或g代理的情况下,以下代码应产生相同的效果

# -*- coding: utf-8 -*-
from flask import render_template, redirect
from application import app
from contextlib import closing
import sqlite3

def get_db():
    return sqlite3.connect('test.db')

@app.route('/')
def index():
    with closing(get_db()) as conn:
        cur = conn.cursor()
        cur.execute('select * from users')
        select = cur.fetchall()
    return render_template('index.html', title='DBSelectTest', posts=select)

我的强烈建议是使用SQLAlchemy,即使与我将留给其他人的您的问题无关。即使你可能认为一开始很难,而且更复杂,但从长远来看,它的回报是如此之高,以至于你真的不想跳过它。祝你好运,玩得开心:你不是认真的。没有sql炼金术就没有烧瓶给你我没有说过我不会使用炼金术,我只是问了一个具体的问题。如果您不完全理解它是如何工作的,我相信sql炼金术不会对您有所帮助。我是关于基本知识和技能的。好问题。尽管大多数烧瓶示例/教程使用sqlalchemy,但这完全是可选的。随着烧瓶的破裂 它不会为您做出很多决策,例如使用哪个数据库。有时ORM是完成任务的合适工具,有时则不然。始终最好了解发动机罩下发生的事情,以便做出明智的决定。