【Python百日进阶-Web开发-Peewee】Day248 - 数据库 框架集成

文章目录

    • 6.10 框架集成
      • 6.10.1 Flask
      • 6.10.2 Django
      • 6.10.3 Bottle
      • 6.10.4 Web.py
      • 6.10.5 Tornado
      • 6.10.6 Wheezy.web
      • 6.10.7 Falcon
      • 6.10.8 Pyramid
      • 6.10.9 CherryPy
      • 6.10.10 Sanic
      • 6.10.11 FastAPI
      • 6.10.12 其他框架
    • 6.11 执行查询

6.10 框架集成

对于 Web 应用程序,通常在收到请求时打开连接,并在传递响应时关闭连接。在本节中,我将描述如何向您的 Web 应用程序添加挂钩,以确保正确处理数据库连接。

这些步骤将确保无论您使用的是简单的 SQLite 数据库,还是多个 Postgres 连接池,peewee 都能正确处理连接。

笔记

接收大量流量的应用程序可能会受益于使用 连接池来降低在每个请求上建立和拆除连接的成本。

6.10.1 Flask

Flask 和 peewee 是一个很棒的组合,是任何规模项目的首选。Flask 提供了两个钩子,我们将使用它们来打开和关闭我们的数据库连接。我们将在收到请求时打开连接,然后在返回响应时关闭它。

from flask import Flask
from peewee import *

database = SqliteDatabase('my_app.db')
app = Flask(__name__)

# This hook ensures that a connection is opened to handle any queries
# generated by the request.
@app.before_request
def _db_connect():
    database.connect()

# This hook ensures that the connection is closed when we've finished
# processing the request.
@app.teardown_request
def _db_close(exc):
    if not database.is_closed():
        database.close()

6.10.2 Django

虽然 peewee 与 Django 一起使用的情况不太常见,但实际上两者都很容易使用。要使用 Django 管理您的 peewee 数据库连接,我认为最简单的方法是在您的应用程序中添加一个中间件。中间件应该是中间件列表中的第一个,以确保它在处理请求时首先运行,并在返回响应时最后运行。

如果您有一个名为my_blog的 django 项目,并且您的 peewee 数据库在模块中定义my_blog.db,您可以添加以下中间件类:

# middleware.py
from my_blog.db import database  # Import the peewee database instance.


def PeeweeConnectionMiddleware(get_response):
    def middleware(request):
        database.connect()
        try:
            response = get_response(request)
        finally:
            if not database.is_closed():
                database.close()
        return response
    return middleware


# Older Django < 1.10 middleware.
class PeeweeConnectionMiddleware(object):
    def process_request(self, request):
        database.connect()

    def process_response(self, request, response):
        if not database.is_closed():
            database.close()
        return response

为确保执行此中间件,请将其添加到您的settings模块中:

# settings.py
MIDDLEWARE_CLASSES = (
    # Our custom middleware appears first in the list.
    'my_blog.middleware.PeeweeConnectionMiddleware',

    # These are the default Django 1.7 middlewares. Yours may differ,
    # but the important this is that our Peewee middleware comes first.
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
)

# ... other Django settings ...

6.10.3 Bottle

我自己没有使用过Bottle,但是查看文档我相信以下代码应该确保数据库连接得到正确管理:

# app.py
from bottle import hook  #, route, etc, etc.
from peewee import *

db = SqliteDatabase('my-bottle-app.db')

@hook('before_request')
def _connect_db():
    db.connect()

@hook('after_request')
def _close_db():
    if not db.is_closed():
        db.close()

# Rest of your bottle app goes here.

6.10.4 Web.py

请参阅 应用程序处理器的文档。

db = SqliteDatabase('my_webpy_app.db')

def connection_processor(handler):
    db.connect()
    try:
        return handler()
    finally:
        if not db.is_closed():
            db.close()

app.add_processor(connection_processor)

6.10.5 Tornado

看起来 Tornado 的RequestHandler类实现了两个钩子,可用于在处理请求时打开和关闭连接。

from tornado.web import RequestHandler

db = SqliteDatabase('my_db.db')

class PeeweeRequestHandler(RequestHandler):
    def prepare(self):
        db.connect()
        return super(PeeweeRequestHandler, self).prepare()

    def on_finish(self):
        if not db.is_closed():
            db.close()
        return super(PeeweeRequestHandler, self).on_finish()

RequestHandler在您的应用程序中,现在您可以扩展默认值,而不是扩展PeeweeRequestHandler.

请注意,这并未解决如何将 peewee 与 Tornado 或其他事件循环异步使用。

6.10.6 Wheezy.web

连接处理代码可以放在中间件中。

def peewee_middleware(request, following):
    db.connect()
    try:
        response = following(request)
    finally:
        if not db.is_closed():
            db.close()
    return response

app = WSGIApplication(middleware=[
    lambda x: peewee_middleware,
    # ... other middlewares ...
])

感谢 GitHub 用户@tuukkamustonen提交此代码。

6.10.7 Falcon

连接处理代码可以放在中间件组件中。

import falcon
from peewee import *

database = SqliteDatabase('my_app.db')

class PeeweeConnectionMiddleware(object):
    def process_request(self, req, resp):
        database.connect()

    def process_response(self, req, resp, resource, req_succeeded):
        if not database.is_closed():
            database.close()

application = falcon.API(middleware=[
    PeeweeConnectionMiddleware(),
    # ... other middlewares ...
])

6.10.8 Pyramid

设置一个处理数据库连接生命周期的请求工厂,如下所示:

from pyramid.request import Request

db = SqliteDatabase('pyramidapp.db')

class MyRequest(Request):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        db.connect()
        self.add_finished_callback(self.finish)

    def finish(self, request):
        if not db.is_closed():
            db.close()

在您的应用程序main()中,确保将MyRequest用作 request_factory:

def main(global_settings, **settings):
    config = Configurator(settings=settings, ...)
    config.set_request_factory(MyRequest)

6.10.9 CherryPy

请参阅发布/订阅模式。

def _db_connect():
    db.connect()

def _db_close():
    if not db.is_closed():
        db.close()

cherrypy.engine.subscribe('before_request', _db_connect)
cherrypy.engine.subscribe('after_request', _db_close)

6.10.10 Sanic

在 Sanic 中,连接处理代码可以放在请求和响应中间件sanic middleware中。

# app.py
@app.middleware('request')
async def handle_request(request):
    db.connect()

@app.middleware('response')
async def handle_response(request, response):
    if not db.is_closed():
        db.close()

6.10.11 FastAPI

与 Flask 类似,FastAPI 提供了两个基于事件的钩子,我们将使用它们来打开和关闭我们的数据库连接。我们将在收到请求时打开连接,然后在返回响应时关闭它。

from fastapi import FastAPI
from peewee import *

db = SqliteDatabase('my_app.db')
app = FastAPI()

# This hook ensures that a connection is opened to handle any queries
# generated by the request.
@app.on_event("startup")
def startup():
    db.connect()


# This hook ensures that the connection is closed when we've finished
# processing the request.
@app.on_event("shutdown")
def shutdown():
    if not db.is_closed():
        db.close()

6.10.12 其他框架

在这里看不到您的框架?请打开 GitHub 票证,我会看到有关添加部分的信息,或者更好的是,提交文档拉取请求。

6.11 执行查询

SQL 查询通常通过调用execute()使用查询构建器 API 构建的查询来执行(或者在查询的情况下通过简单地迭代查询对象Select)。对于希望直接执行 SQL 的情况,可以使用该Database.execute_sql()方法。

db = SqliteDatabase('my_app.db')
db.connect()

# Example of executing a simple query and ignoring the results.
db.execute_sql("ATTACH DATABASE ':memory:' AS cache;")

# Example of iterating over the results of a query using the cursor.
cursor = db.execute_sql('SELECT * FROM users WHERE status = ?', (ACTIVE,))
for row in cursor.fetchall():
    # Do something with row, which is a tuple containing column data.
    pass

你可能感兴趣的:(数据库,python,前端,数据库)