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

时间:2019-04-18 11:05:10

标签: flask

我是Flask和Web编程的新手,所以我试图了解上下文的原理和框架的db操作。 现在,我想弄清楚如何仅使用普通sql就可以在没有Sql-Alchemy和其他ORM的情况下管理数据库连接。

因此,使用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

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中,我们从客户端使用根route(“ /”)进行查询,因此在那一刻以及在该应用程序上下文之后都创建了请求上下文。 因此,据我了解,可以从我们的请求上下文访问“ get_db”,并且我们能够连接到db并在当前踏步内的所有函数中使用该g值?那“ close_connection”呢?由于装饰器“ teardown_appcontext”,必须在应用上下文失败或结束后关闭连接?可以在我的代码中使用吗?

那么,谁能提供使用带有单独连接功能的纯SQL的正确案例?

1 个答案:

答案 0 :(得分:1)

就代码而言,烧瓶应用程序和请求上下文的行为类似于全局变量,但实际上是代理,每次您的应用程序收到新的Web请求时,代理将包含不同的值。请求上下文包含特定于该特定Web请求的数据,例如表单数据,远程IP地址,http标头等。每次接收到Web请求时,都会在调用视图函数之前创建新的应用程序和请求上下文,然后将它们在返回响应并且完成Web请求的处理后销毁。 g代理与应用程序上下文一起存储,并用于存储具有特定Web请求生存期的变量。作为事件和信号的结果,它用于在flask调用的函数之间传递信息。在代码中,您可以使用修饰符向close_connection事件注册函数teardown_appcontext,从而确保在完成每个Web请求的处理后调用该函数。在您的视图函数之前或之后,还可以挂钩执行许多其他事件,以提供请求或响应的预处理。 g代理仅用于存储您在视图函数中创建的数据库连接,并使该连接对保证关闭的close_connection函数可用。如果您的应用程序代码中发生错误,这可以防止数据库连接保持打开状态。此模式用于完成与使用上下文管理器(或尝试,除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)