Spec-Zone.ru › Flask 2.3

Использование SQLite 3 с Flask

В Flask вы можете легко реализовать открытие подключений к базе данных по запросу и закрытие их при завершении контекста (обычно в конце запроса).

Вот простой пример использования SQLite 3 с Flask:

import sqlite3
from flask import g

DATABASE = '/path/to/database.db'

def get_db():
    db = getattr(g, '_database', None)
    if db is None:
        db = g._database = sqlite3.connect(DATABASE)
    return db

@app.teardown_appcontext
def close_connection(exception):
    db = getattr(g, '_database', None)
    if db is not None:
        db.close()

Теперь для использования базы данных приложение должно иметь активный контекст приложения (что всегда верно, если в процессе есть запрос) или создать собственный контекст приложения. В этот момент можно использовать функцию get_db для получения текущего подключения к базе данных. Всякий раз, когда контекст уничтожается, подключение к базе данных будет разорвано.

Пример:

@app.route('/')
def index():
    cur = get_db().cursor()
    ...

Примечание

Пожалуйста, имейте в виду, что функции teardown request и appcontext всегда выполняются, даже если обработчик перед запросом потерпел неудачу или никогда не выполнялся. Из-за этого нам нужно убедиться, что база данных существует перед её закрытием.

Подключение по требованию

Преимущества этого подхода (подключение при первом использовании) заключаются в том, что подключение будет открыто только если это действительно необходимо. Если вы хотите использовать этот код вне контекста запроса, вы можете использовать его в оболочке Python, открыв контекст приложения вручную:

with app.app_context():
    # now you can use get_db()

Легкое выполнение запросов

Теперь в каждой функции обработки запросов вы можете получить доступ к get_db() для получения текущего открытого подключения к базе данных. Для упрощения работы с SQLite полезна функция row factory. Она выполняется для каждого результата, возвращаемого из базы данных, чтобы преобразовать результат. Например, чтобы получить словари вместо кортежей, это можно вставить в функцию get_db , которую мы создали выше:

def make_dicts(cursor, row):
    return dict((cursor.description[idx][0], value)
                for idx, value in enumerate(row))

db.row_factory = make_dicts

Это заставит модуль sqlite3 возвращать словари для этого подключения к базе данных, что намного удобнее. Ещё проще, мы могли бы поместить это в get_db вместо:

db.row_factory = sqlite3.Row

Это будет использовать объекты Row вместо словарей для возврата результатов запросов. Это объекты namedtuple , поэтому к ним можно получить доступ по индексу или по ключу. Например, предположим, что у нас есть объект sqlite3.Row под названием r для строк id, FirstName, LastName и MiddleInitial.

>>> # You can get values based on the row's name
>>> r['FirstName']
John
>>> # Or, you can get them based on index
>>> r[1]
John
# Row objects are also iterable:
>>> for value in r:
...     print(value)
1
John
Doe
M

Кроме того, рекомендуется предоставить функцию запроса, которая объединяет получение курсора, выполнение и извлечение результатов:

def query_db(query, args=(), one=False):
    cur = get_db().execute(query, args)
    rv = cur.fetchall()
    cur.close()
    return (rv[0] if rv else None) if one else rv

Эта полезная функция в сочетании с функцией row factory делает работу с базой данных намного приятнее, чем использование только объектов курсора и подключения.

Вот как вы можете её использовать:

for user in query_db('select * from users'):
    print(user['username'], 'has the id', user['user_id'])

Или если вам нужен только один результат:

user = query_db('select * from users where username = ?',
                [the_username], one=True)
if user is None:
    print('No such user')
else:
    print(the_username, 'has the id', user['user_id'])

Для передачи переменных частей в SQL-запрос используйте знак вопроса в запросе и передавайте аргументы в виде списка. Никогда не добавляйте их непосредственно в SQL-запрос с помощью форматирования строк, так как это позволяет атаковать приложение с помощью SQL-инъекций.

Изначальные схемы

Реляционные базы данных нуждаются в схемах, поэтому приложения часто поставляют файл schema.sql, который создаёт базу данных. Хорошо предоставить функцию, которая создаёт базу данных на основе этой схемы. Эта функция может сделать это за вас:

def init_db():
    with app.app_context():
        db = get_db()
        with app.open_resource('schema.sql', mode='r') as f:
            db.cursor().executescript(f.read())
        db.commit()

Затем вы можете создать такую базу данных из оболочки Python:

>>> from yourapplication import init_db
>>> init_db()

© 2007–2022 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/2.3.x/patterns/sqlite3/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API