Sqlalchemy backref что это
Операции с таблицами через Flask-SQLAlchemy
На предыдущем занятии мы с вами создали две таблицы, используя механизм SQLAlchemy, и объявили функцию-представления для регистрации новых пользователей. И теперь пришло время разобраться с чтением данных из таблиц.
Выборка записей из таблиц
Как вы помните, у нас в БД две таблицы, причем, они связаны между собой через внешний ключ user_id таблицы profiles:
Наша задача сделать выборку по пользователям, в которой бы фигурировали данные из обеих таблиц. Но для начала посмотрим, как вообще осуществляется получение данных. Для демонстрации я перейду в консоль Python и выполню команду:
то есть, из нашего текущего модуля app импортируем переменную db и классы Users, Profiles. Далее, чтобы выбрать все записи, например, из таблицы users, следует выполнить метод all объекта query:
и на выходе получим список объектов, которые отображаются в соответствии с определением магического метода __repr__ в классе Users:
Здесь объект query берется из базового класса db.Model, от которого образованы классы Users и Profiles. Благодаря концепции наследования в ООП, мы автоматически получаем полный функционал для работы с таблицами БД.
Давайте теперь сохраним возвращаемый список в переменной res:
и посмотрим на ее содержимое. Мы видим, что это коллекция объектов и каждый объект содержит атрибуты: id, email, psw, date. Как раз те, что мы определяли в классе Users и те, что были прочитаны из соответствующей таблицы БД. То есть, мы можем обратиться к любому элементу и вывести нужное нам свойство, например, так:
Получим email из первой записи.
По аналогии работает метод first, только он возвращает первую запись, соответствующего запроса (или значение None, если ничего нет):
Далее, для выбора записей по определенному критерию можно воспользоваться методы filter_by и filter:
Разница между этими методами в том, что в filter_by передаются именованные параметры, а в filter прописывается логическое выражение. Поэтому последний метод обладает большей гибкостью, например, можно вывести все записи с id>1:
Также можно делать ограничение на максимальное число возвращаемых записей:
Выполнять сортировку по определенному полю:
Или, просто получать пользователя по значению первичного ключа:
Разумеется, все эти методы можно комбинировать и создавать более сложные запросы.
Выборка из нескольких таблиц
Ну хорошо, мы увидели как можно выбирать записи из одной конкретной таблицы. Но как объединить данные, например, из двух наших таблиц и сформировать одну общую выборку? Для этого нужно соединить записи таблиц по внешнему ключу user_id, следующим образом:
Здесь вначале в методе query указываются таблицы, формирующие выборку. Затем, используется метод join, в котором прописывается условие связывания записей этих двух таблиц. И в конце, метод all возвращает все записи, удовлетворяющие запросу.
На выходе переменная res будет ссылаться на список, содержащий выбранные данные. К ним можно обратиться, используя следующую конструкцию:
Однако, SQLAlchemy предоставляет нам еще один довольно удобный механизм связывания таблиц. Если мы наперед знаем, что необходимо выбирать для каждого пользователя информацию из таблиц users и profiles, то в классе Users, как таблицы с «первичными данными», к которой подбираются соответствующие записи из «вторичной таблицы» profiles, можно прописать специальную переменную:
Через эту переменную будет устанавливаться связь с таблицей Profiles по внешнему ключу user_id. Параметр backref указывает таблицу, к которой присоединять записи из таблицы profiles. Последнее значение uselist=False указывает, что одной записи из users должна соответствовать одна запись из profiles, что, в общем-то, и должно быть.
Теперь, выполняя простую команду:
в объектах списка будет присутствовать атрибут pr, который ссылается на объект Profiles с соответствующими данными:
Как видите, все довольно удобно. Мы воспользуемся этим механизмом и отобразим на главной странице сайта список зарегистрированных пользователей:
И модифицируем шаблон:
Все, теперь на главной странице видим информацию о пользователях из обеих таблиц.
Заключение
На этом мы завершим серию занятий по микрофреймворку Flask. Конечно, коснуться всех деталей в рамках видеоуроков просто нереально. В частности, модуль SQLAlchemy нами был рассмотрен лишь обзорно, чтобы дать основные представления об этом весьма полезном расширении, которое повсеместно используется при работе с БД. И, если вы задумали создать сайт на Flask, то обязательно используйте его (или какой-либо подобный) для работы с таблицами БД. Это избавит вас в будущем от большого количества проблем, и, кроме того, при трудоустройстве по этому профилю знание SQLAlchemy будет весьма кстати. Хорошей отправной точкой в его изучении будет страница документации на русском языке:
Видео по теме
Flask #1: Что это такое? Простое WSGI-приложение
Flask #2: Использование шаблонов страниц сайта
Flask #3: Контекст приложения и контекст запроса
Flask #4: Функция url_for и переменные URL-адреса
Flask #5: Подключение внешних ресурсов и работа с формами
Flask #7: Декоратор errorhandler, функции redirect и abort
Flask #8: Создание БД, установление и разрыв соединения при запросах
Flask #9: Добавление и отображение статей из БД
Flask #10: Способ представления полноценных HTML-страниц на сервере
Flask #11: Формирование ответа сервера, декораторы перехвата запроса
Flask #12: Порядок работы с cookies (куками)
Flask #13: Порядок работы с сессиями (session)
Flask #14: Регистрация пользователей и шифрование паролей
Flask #15: Авторизация пользователей на сайте через Flask-Login
Flask #16: Улучшение процесса авторизации (Flask-Login)
Flask #17: Загрузка файлов на сервер и сохранение в БД
Flask #18: Применение WTForms для работы с формами сайта
Flask #19: Обработка ошибок во Flask-WTF
Flask #23: Операции с таблицами через Flask-SQLAlchemy
© 2021 Частичное или полное копирование информации с данного сайта для распространения на других ресурсах, в том числе и бумажных, строго запрещено. Все тексты и изображения являются собственностью сайта
Шпаргалка по SQLAlchemy
Эта шпаргалка поможет вам хорошо понять SQLAlchemy.
Вступление
SQLAlchemy-это глубокая и мощная вещь, состоящая из многих слоев. Эта шпаргалка прилипает к частям слоя ORM (Object Relational Mapper) и предназначена для использования в качестве ссылки,а не учебника. Тем не менее, если вы знакомы с SQL, то эта шпаргалка должна помочь вам хорошо понять SQLAlchemy.
Основные модели
Одна модель используется для описания одной таблицы базы данных. Например:
Запросы и взаимодействия
Выбор и фильтрация
Отношения
Отношения между таблицами SQL описываются в терминах отношений внешних ключей. В приведенном примере таблица books имеет поле внешнего ключа, указывающее на поле id таблицы authors. SQLAlchemy делает использование и изучение этих отношений довольно простым.
Отношения один ко многим
Предположим, мы следим за книгами разных авторов. Один автор может иметь много книг.
Вот несколько способов, которыми вы можете использовать отношения после их настройки:
Отношения один к одному
Многие ко многим отношениям
Отношение “многие ко многим” требует дополнительной таблицы для создания сопоставлений между строками. Есть два способа сделать это:
Во-первых, просто использование моделей:
Этот следующий подход лучше, если ваша таблица карт является только таблицей карт и не требует сложных взаимодействий:
Вы можете использовать эти отношения следующим образом:
Иногда у вас есть таблица с внешним ключом, указывающим на ту же таблицу. Например, предположим, что у нас есть куча узлов в направленном дереве. Узел может иметь много дочерних узлов, но не более одного родительского
Вы можете использовать эти отношения, как и любые отношения “многие к одному”:
Несколько связей с одной и той же таблицей
Вы можете взаимодействовать с этим так же, как с двумя отношениями “много к одному”.
Declaring Models¶
Generally Flask-SQLAlchemy behaves like a properly configured declarative base from the declarative extension. As such we recommend reading the SQLAlchemy docs for a full reference. However the most common use cases are also documented here.
Things to keep in mind:
Some parts that are required in SQLAlchemy are optional in Flask-SQLAlchemy. For instance the table name is automatically set for you unless overridden. It’s derived from the class name converted to lowercase and with “CamelCase” converted to “camel_case”. To override the table name, set the __tablename__ class attribute.
Simple Example¶
A very simple example:
a string with a maximum length (optional in some databases, e.g. PostgreSQL)
some longer unicode text
date and time expressed as Python datetime object.
stores floating point values
stores a boolean value
stores a pickled Python object
stores large arbitrary binary data
One-to-Many Relationships¶
The most common relationships are one-to-many relationships. Because relationships are declared before they are established you can use strings to refer to classes that are not created yet (for instance if Person defines a relationship to Address which is declared later in the file).
Relationships are expressed with the relationship() function. However the foreign key has to be separately declared with the ForeignKey class:
So what do backref and lazy mean? backref is a simple way to also declare a new property on the Address class. You can then also use my_address.person to get to the person at that address. lazy defines when SQLAlchemy will load the data from the database:
‘select’ / True (which is the default, but explicit is better than implicit) means that SQLAlchemy will load the data as necessary in one go using a standard select statement.
‘joined’ / False tells SQLAlchemy to load the relationship in the same query as the parent using a JOIN statement.
‘subquery’ works like ‘joined’ but instead SQLAlchemy will use a subquery.
How do you define the lazy status for backrefs? By using the backref() function:
Many-to-Many Relationships¶
If you want to use many-to-many relationships you will need to define a helper table that is used for the relationship. For this helper table it is strongly recommended to not use a model but an actual table:
Еще один пошаговый учебник SQLalchemy (часть 2 из 2)
Получите практические, реальные навыки Python на наших ресурсах и пути
В первой части этой серии мы пошли, что некоторые могут вызвать метод «SQL-выражения SQL» использования SQLALCHMEY, чтобы взаимодействовать с вашей базой данных. Теория за этим заключается в том, что мы должны учиться менее абстрактным способом делать вещи, прежде чем добраться до более высокого уровня (и более абстрактных) методов. Это верно во многих математических классах, таких как исчисление, в котором вы изучаете долгий путь, чтобы найти стандартное отклонение некоторых калитков, прежде чем узнать о ярлыке.
На второй половину мы будем делать то, что может сказать, это простой способ использовать SQLALCHEMY. Это известен как метод «Объект реляционного» и Официальная документация на самом деле начинается с этого. Эта методология изначально занимает немного больше времени, но во многих отношениях также намного проще следовать.
Привыкание к отображениям данных
Старая школа Робина Мунна Учебное пособие SQLALCHEMY Вызывается этот раздел «Картирование данных», потому что мы будем отображать данные в базе данных на классы Python. Давайте начнем!
Первое отличие, чтобы принять к сведению по сравнению с нашими предыдущими примерами, это Пользователь класс. Мы изменили наш оригинальный пример (см. Часть) немного, чтобы соответствовать тому, что на официальной документации, а именно параметры теперь имеются, полное имя и пароль. Остальные должны выглядеть одинаково, пока не доберемся до Mapper утверждение. Этот удобный метод позволяет SQLALCHEMY для отображения пользовательского класса пользователей_табели. Это может показаться не иметь большого значения, но этот метод делает добавление пользователей в базу данных гораздо более простым.
Однако, прежде чем мы доберемся до этого, нам нужно обсудить Декларативный конфигурационный стиль Отказ Хотя стиль выше дает нам гранулированный контроль над столом, Mapper и Class, по большей части нам не нужно, чтобы быть таким сложным. Вот где приходит декларативный стиль. Это делает настройку всего еще проще. Первый декларативный стиль, который я знал, было дополнением для SQLALCHEMY, называемой Эликсир Отказ Этот встроенный декларативный стиль не так полно, как эликсир, но он укормит, потому что у вас нет дополнительной зависимости. Давайте посмотрим, насколько декларативно отличается:
Класс сейчас в сессии
Красота использования реляционного метода объекта для взаимодействия с нашей базой данных может быть показана в нескольких фрагментах быстрого кода. Давайте посмотрим, как мы можем создать ряд:
Как видите, мы можем создавать пользователей с классом пользователя. Мы можем использовать точечную обозначение для доступа к атрибутам, как мы бы в любом другом классе Python. Мы можем даже использовать их для обновления строк. Например, если нам нужно изменить объект пользователя выше, мы сделаем следующее:
Обратите внимание, что ничто из этого не добавит строку в базу данных автоматически, как эти методы вставки, на которых мы смотрели в нашей первой статье. Вместо этого нам нужен объект сеанса для этого. Давайте пройдемся через некоторые основы использования сеанса:
Мы приостановимся здесь, чтобы объяснить, что происходит. Сначала нам нужно импортировать SessionMaker от sqlalchemy.orm И связывайте его с двигателем (технически, вы можете создать сеанс без привязки, но чтобы сделать что-нибудь полезное, вам нужно будет связать его в конце концов). Далее мы создаем экземпляр сеанса. Затем мы создали объект пользователя и добавьте его на сеанс. На данный момент код SQL не был запущен, и транзакция только в ожидании. Чтобы сохранить эту строку, нам нужно позвонить session.commit () или запустить запрос.
Если вам нужно добавить несколько пользователей, вы делаете это:
Если вы произошли, чтобы изменить один из атрибутов пользователя после совершения его в базу данных, вы можете использовать Session.dirty Чтобы проверить, какой из них был изменен. Если вам просто нужно знать, какие строки в ожидании, звоните Session.new Отказ Наконец, мы можем использовать Session.Rollback () откат транзакции.
Теперь давайте посмотрим на некоторые образец запросов:
Нам не нужно проходить каждый из них, поскольку у всех нас есть объяснения в комментариях. Вместо этого мы перейдем к теме присоединения.
Присоединиться к веселью
Есть присоединения, используя Синтаксис выражения SQL Что я не буду покрывать здесь. Скорее, мы будем использовать реляционную методологию объекта. Если вы оглядываетесь в любой из начинающих примеров для создания таблиц, вы заметите, что мы уже настроили соединение с Иностранник объект. Декларативный формат выглядел так:
Посмотрим, как это работает, создавая новый пользователь:
Из-за Иностранник и Backref Команда, Пользователь Объект имеет адреса атрибут. Если вы запустите этот код, вы увидите, что он пуст. Давайте добавим некоторые адреса! (Примечание. Обязательно добавьте пользователя PROF на сеанс: Session.add (проф))))
Увидеть, как было легко? Еще легко получить информацию обратно. Например, если вы хотите получить доступ только к первому адресу, вы бы просто позвонили prof.addresses [0] Отказ Теперь скажем, что вам нужно изменить один из адресов (I.e. сделать обновление). Это так просто, как пирог:
Теперь давайте перейдем к выполнению запросов на присоединениях:
Это один длинный запрос! Я нахожу тех, кто трудно следовать за собой, поэтому я обычно делаю следующее, чтобы облегчить мою мозгу:
Теперь, для тех из вас, что любят одноинал, в первом примере нет ничего плохого. Он будет производить точно такие же результаты. Я просто случился, чтобы упростить более длинную версию для отладки. Наконец, мы также можем использовать реальное соединение:
Это также делает то же самое, что и предыдущие два примера, но более четко. Для получения дополнительной информации о присоединениях с помощью реляционного синтаксиса объекта я рекомендую Официальная документация Отказ
Обертывание
На данный момент вы должны быть в состоянии создать вашу базу данных с таблицами, заполнять таблицы с данными, а также выбирать, обновлять и совершать транзакции в вашу базу данных с помощью SQLALCHEMY. Я надеюсь, что вы нашли этот учебник полезным в понимании этой удивительной технологии.
Примечание. Этот учебник был протестирован на Windows с Python 2.5 и SQLALCHEMY 0.5.8.
SQLAlchemy — many-to-many
Описание связи many-to-many (многие ко многим) в SQLAlchemy. Пример создания таблиц и сохранения данных.
Описание моделей (классов)
Мы создаем два класса: Task и Category, в одной таблице будут сохранятся задачи, в другой категории.
Таблица задач
Таблица категорий
У одной задачи может быть несколько категорий. Для этих целей наилучшим образом подойдет сохранение связи между задачей и категорией в отдельной таблице. Это будет третья таблица, которая будет создана с помощью связи db.relationship.
Все это делается описанием классов моделей таким образом:
# ploshadka.net
from datetime import datetime
from flask_login import UserMixin
from flask_security import RoleMixin
Если требуется в дальнейшем удалять одной командой все связанные данные, то в db.relationship надо добавить пару дополнительных свойств такого плана:
Однако в данном примере это не подходит, иначе удалив задачу с привязанной к ней категорией, мы удалим эти категории из всех других задач в том числе.
Как сохранить данные
Пример ниже представляет из себя методы с роутом (через блюпринт). Она получает данные через метод POST. Затем эти данные сохраняются в БД и возвращаются обратно.
Внутри методов осуществляется сохранение задачи, категорий и связи с ними. Все основные моменты пояснены в первом методе.
Метод сохранения к задаче одной категории
# Данные с фронта
data = request. get_json ( )
name = data [ ‘name’ ]
category = data [ ‘category’ ]
# Вернем обновленные данные обратно на фронт
return get_items ( )
Метод сохранения к задаче несколько категорий
В этом случае наш метод немного изменится. С фронта мы получаем список категорий через запятую. Формируем из этой строки список категорий. Проверяем каждую категорию на существование в базе данных. Затем или добавляем к задаче её или создаём и опять же добавляем к задаче.
# Получим данные с фронта
data = request. get_json ( )
name = data [ ‘name’ ]
categories = data [ ‘categories’ ]
# Сделаем лист из нескольких категорий (разделим их по запятым)
categories = [ x. strip ( ) for x in categories. split ( ‘,’ ) ]
# Для каждой категории
for category_name in categories:
# Вернем обновленные данные
return get_items ( )
Как получить задачи по категориям
Мы должны в класс категорий:
Теперь мы можем получать задачи по id категории так:
Получение сериализованных данных
Также эти данные можно получить сериализованными (обработанными).
Запросим обработанные данные:
Для этого в метод Task (не перепутайте) надо добавить обработку:
Еще один пример выборки many to many
Вот как можно отобрать task-и из категорий:
def get_tasks_by_category ( cat_id ) :
return json. dumps ( tasks )
Из участка выше, это:
Можно также записать так:
Читайте также
Кстати, на сайте нет рекламы. У сайта нет цели самоокупаться, но если вам пригодилась информация можете задонатить мне на чашечку кофе в макдаке. Лайкнуть страницу или просто поблагодарить. Карма вам зачтется.
Комментарии к статье “ SQLAlchemy — many-to-many ” (2)
Только изучаю python вообще и flask в частности, возник вопрос по коду:
># Вернем обновленные данные обратно на фронт
> return get_items()
Нет перенаправления и рендера, значит ответ функции обрабатывается через ajax скриптами на фронте? Изначально подумал, что просто вызов из другого места, но тогда не было бы роута в заголовке функции.
Или это придуманный пример и полная функциональность не прописана изначально?
Код рабочий, сокращенный вариант, вырезанный из рабочей структуры.
return get_items() — в данном примере это не важно и поэтому не расписано. Эта ссылка на функцию получения всех элементов в БД, чтобы отправить на фронт. Можно ничего не отправлять или отправить что-то другое, зависит от того, что ожидает фронт.
В этом примере приведен только бэк, потому что фронт может быть на любой технологии и это никак не изменит бэк. У меня, например, со стороны фронта этот код обрабатывается на svelte.
По flask написан большой гайд. Может найдете что-то полезное.