Spec-Zone.ru › Flask 3.0

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

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

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

© 2010 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/3.0.x/patterns/sqlite3/

Spec-Zone.ru

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