Spec-Zone.ru › Flask 1.1

Использование 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 для получения текущего подключения к базе данных. При каждом уничтожении контекста подключение к базе данных будет закрыто.

Примечание: если вы используете Flask 0.9 или более раннюю версию, вам необходимо использовать flask._app_ctx_stack.top вместо g, так как объект flask.g был связан с запросом, а не контекстом приложения.

Пример:

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

Примечание

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

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

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

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

Легкий запрос

Теперь в каждой функции обработки запросов вы можете получить доступ к get_db() для получения текущего открытого подключения к базе данных. Для упрощения работы с SQLite полезна функция обработки строк. Она выполняется для каждого результата, возвращаемого из базы данных, чтобы преобразовать результат. Например, для получения словарей вместо кортежей это можно вставить в функцию 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

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

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

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–2020 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/1.0.x/patterns/sqlite3/

Spec-Zone.ru

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