Spec-Zone.ru › Flask 0.12

SQLAlchemy в Flask

Многие предпочитают SQLAlchemy для доступа к базам данных. В этом случае рекомендуется использовать пакет, а не модуль для вашего приложения Flask и поместить модели в отдельный модуль (Приложения большего размера). Хотя это не обязательно, это имеет большой смысл.

Существует четыре очень распространённых способа использования SQLAlchemy. Я опишу каждый из них здесь:

Расширение Flask-SQLAlchemy

Поскольку SQLAlchemy — это распространённый абстрактный уровень баз данных и объектно-реляционный маппер, который требует небольших усилий по настройке, существует расширение Flask, которое обрабатывает это за вас. Это рекомендуется, если вы хотите быстро начать работу.

Вы можете загрузить Flask-SQLAlchemy с PyPI.

Декларативный подход

Декларативный подход в SQLAlchemy — это самый современный метод использования SQLAlchemy. Он позволяет определить таблицы и модели за один раз, аналогично тому, как работает Django. В дополнение к следующему тексту я рекомендую ознакомиться с официальной документацией по декларативному расширению.

Вот пример database.py модуля для вашего приложения:

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
db_session = scoped_session(sessionmaker(autocommit=False,
                                         autoflush=False,
                                         bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()

def init_db():
    # import all modules here that might define models so that
    # they will be registered properly on the metadata.  Otherwise
    # you will have to import them first before calling init_db()
    import yourapplication.models
    Base.metadata.create_all(bind=engine)

Для определения ваших моделей просто унаследуйте от Base класса, созданного кодом выше. Если вы задаетесь вопросом, почему нам не нужно беспокоиться о потоках здесь (как мы делали в примере SQLite3 выше с объектом g): это потому, что SQLAlchemy уже делает это за нас с scoped_session.

Чтобы использовать SQLAlchemy декларативным способом в вашем приложении, просто поместите следующий код в модуль приложения. Flask автоматически удалит сессии базы данных в конце запроса или при завершении работы приложения:

from yourapplication.database import db_session

@app.teardown_appcontext
def shutdown_session(exception=None):
    db_session.remove()

Вот пример модели (поместите её в models.py, например):

from sqlalchemy import Column, Integer, String
from yourapplication.database import Base

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(50), unique=True)
    email = Column(String(120), unique=True)

    def __init__(self, name=None, email=None):
        self.name = name
        self.email = email

    def __repr__(self):
        return '<User %r>' % (self.name)

Для создания базы данных можно использовать функцию init_db:

>>> from yourapplication.database import init_db
>>> init_db()

Вы можете вставлять записи в базу данных так:

>>> from yourapplication.database import db_session
>>> from yourapplication.models import User
>>> u = User('admin', 'admin@localhost')
>>> db_session.add(u)
>>> db_session.commit()

Запросы также просты:

>>> User.query.all()
[<User u'admin'>]
>>> User.query.filter(User.name == 'admin').first()
<User u'admin'>

Ручное отображение объектов-отношений

Ручное отображение объектов-отношений имеет несколько преимуществ и недостатков по сравнению с декларативным подходом, описанным выше. Основное отличие заключается в том, что вы определяете таблицы и классы отдельно и сопоставляете их вместе. Это более гибко, но немного больше работы. В целом, он работает так же, как декларативный подход, поэтому убедитесь, что вы также разделили ваше приложение на несколько модулей в пакете.

Вот пример database.py модуля для вашего приложения:

from sqlalchemy import create_engine, MetaData
from sqlalchemy.orm import scoped_session, sessionmaker

engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
metadata = MetaData()
db_session = scoped_session(sessionmaker(autocommit=False,
                                         autoflush=False,
                                         bind=engine))
def init_db():
    metadata.create_all(bind=engine)

Как и в декларативном подходе, вам необходимо закрывать сессию после каждого запроса или завершения контекста приложения. Поместите это в модуль приложения:

from yourapplication.database import db_session

@app.teardown_appcontext
def shutdown_session(exception=None):
    db_session.remove()

Вот пример таблицы и модели (поместите это в models.py):

from sqlalchemy import Table, Column, Integer, String
from sqlalchemy.orm import mapper
from yourapplication.database import metadata, db_session

class User(object):
    query = db_session.query_property()

    def __init__(self, name=None, email=None):
        self.name = name
        self.email = email

    def __repr__(self):
        return '<User %r>' % (self.name)

users = Table('users', metadata,
    Column('id', Integer, primary_key=True),
    Column('name', String(50), unique=True),
    Column('email', String(120), unique=True)
)
mapper(User, users)

Запросы и вставки работают точно так же, как в примере выше.

Абстрактный уровень SQL

Если вы хотите использовать только абстрактный уровень системы баз данных (и SQL), вам в основном нужен только движок:

from sqlalchemy import create_engine, MetaData, Table

engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
metadata = MetaData(bind=engine)

Затем вы можете либо объявить таблицы в своем коде, как в примерах выше, либо загрузить их автоматически:

from sqlalchemy import Table

users = Table('users', metadata, autoload=True)

Для вставки данных можно использовать метод insert. Сначала необходимо получить соединение, чтобы мы могли использовать транзакцию:

>>> con = engine.connect()
>>> con.execute(users.insert(), name='admin', email='admin@localhost')

SQLAlchemy автоматически выполнит коммит за нас.

Для запроса к вашей базе данных используйте движок напрямую или соединение:

>>> users.select(users.c.id == 1).execute().first()
(1, u'admin', u'admin@localhost')

Эти результаты также являются кортежами, похожими на словари:

>>> r = users.select(users.c.id == 1).execute().first()
>>> r['name']
u'admin'

Вы также можете передавать строки SQL-запросов методу execute():

>>> engine.execute('select * from users where id = :1', [1]).first()
(1, u'admin', u'admin@localhost')

Дополнительную информацию о SQLAlchemy вы найдете на сайте.

© 2007–2020 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/0.12.x/patterns/sqlalchemy/

Spec-Zone.ru

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