flask - Flask,管理数据库连接(无 ORM)
问题描述
总的来说,我是 Flask 和网络编程的新手,所以我试图了解框架的上下文和数据库操作的原理。现在我想弄清楚如何在没有 Sql-Alchemy 和其他 ORM 的情况下管理数据库连接,只需使用普通 sql。
所以使用 sqlite3 db 的简单示例。我的测试项目的结构:
.
├── application
│ ├── __init__.py
│ ├── routes.py
│ └── templates
│ ├── base.html
│ ├── index.html
├── config.py
├── requirements.txt
├── run.py
└── test.db
初始化.py
from flask import Flask,g
from config import Config
import sqlite3
app = Flask(__name__)
app.config.from_object(Config)
def get_db():
db = getattr(g, '_database', None)
if db is None:
db = g._database = sqlite3.connect('test.db')
return db
@app.teardown_appcontext
def close_connection(exception):
db = getattr(g, '_database', None)
if db is not None:
db.close()
from application import routes
路线.py
# -*- coding: utf-8 -*-
from flask import render_template,redirect
from application import app, get_db
# import sqlite3
@app.route('/')
def index():
cur = get_db().cursor()
cur.execute('select*from users')
select=cur.fetchall()
return render_template('index.html',title='DBSelectTest', posts=select)
我已经从 Flask 框架的官方站点复制了“get_db”和“close_connection”函数,但是我不清楚它是如何工作的,如果我只对“def get_db”使用没有“g”的简单代码会有什么区别“ 像这样:
con = sqlite3.connect("catalog.db")
cur = con.cursor()
并且显然在查询完成后关闭连接是这样的:
cur.close()
con.close()
我只是想通过使用 g 来了解应用程序和请求上下文在这种情况下是如何工作的。在这种情况下,我不明白什么是“请求”的主要问题。
我对这个案例的错误理解:
因此,在init .py 中,我们创建了“全局变量”g,它位于应用程序上下文中,并且应该可以被请求上下文中的每个踏板访问。在 routes.py 中,我们使用 root route("/") 从客户端获取查询,因此在那一刻创建了请求上下文,并且在该应用程序上下文之后也是如此。因此,据我了解,“get_db”可以从我们的请求上下文中访问,并且我们能够连接到数据库并在当前胎面内的所有函数中使用该 g 值?那么“close_connection”呢?由于装饰器“teardown_appcontext”,连接必须在应用上下文失败或结束后关闭?它会在我的代码中工作吗?
那么,任何人都可以提供使用带有单独连接功能的普通 sql 的正确案例吗?
解决方案
Flask 应用程序和请求上下文在您的代码中表现得像全局变量,但实际上是代理,每次您的应用程序收到新的 Web 请求时都会包含不同的值。请求上下文包含特定于该特定 Web 请求的数据,例如表单数据、远程 IP 地址、http 标头等。
每次收到 Web 请求时,都会在调用视图函数之前创建新的应用程序和请求上下文,然后在返回响应并完成 Web 请求的处理后销毁这些上下文。代理与应用程序上下文一起存储,g
它用于存储具有特定 Web 请求生命周期的变量。这用于在flask调用的函数之间传递信息,作为事件和信号的结果。
在您的代码中,您使用装饰器将函数注册到close_connection
事件teardown_appcontext
中,从而保证在完成每个 Web 请求的处理后调用它。还有许多其他事件可以在视图函数之前或之后执行,以提供请求或响应的预处理和后处理。代理仅用于存储在视图函数中创建的g
数据库连接,并使其可用于close_connection
保证关闭的函数。如果您的应用程序代码中发生错误,这可以防止数据库连接保持打开状态。
如下所示,该模式用于完成与使用上下文管理器(或 try、except、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)
推荐阅读
- django - Angular应用一直说消息不存在
- reactjs - React Hook Form:isDirty 在负载上不起作用
- python - 使用 python 配置 mongodb 时 SSL 证书验证失败
- python - 如何使用嵌套的 for 循环解决 numba 降低错误?
- maven - Dspace 安装在内核失败
- flask - 无法使用 boto3 和烧瓶上传到 s3
- javascript - 如何在 ng-bootstrap 上使用 NgNav 渲染可滚动的垂直导航?
- javascript - 打字稿:是否可以只为导出类型中的一个键设置状态?
- c# - 如何在c#中对相似值数组进行分组
- swift - 使用 Realm freeze() 方法获取整个 Swift 项目中的对象是否安全?