Db create all не работает

SQLAlchemy create_all() does not create tables

I’m trying to integrate PostgreSQL and SQLAlchemy but SQLAlchemy.create_all() is not creating any tables from my models.

But I get this error: sqlalchemy.exc.ProgrammingError: (ProgrammingError) relation «user» does not exist

How can I fix this?

3 Answers 3

You should put your model class before create_all() call, like this:

If your models are declared in a separate module, import them before calling create_all() .

Say, the User model is in a file called models.py ,

Important note: It is important that you import your models after initializing the db object since, in your models.py _you also need to import the db object from this module.

This is probably not the main reason why the create_all() method call doesn’t work for people, but for me, the cobbled together instructions from various tutorials have it such that I was creating my db in a request context, meaning I have something like:

I also have a separate cli command that also does the create_all:

I also am using a application factory.

When the cli command is run, a new app context is used, which means a new db is used. Furthermore, in this world, an import model in the init_db method does not do anything, because it may be that your model file was already loaded(and associated with a separate db).

The fix that I came around to was to make sure that the db was a single global reference:

I have not dug deep enough into flask, sqlalchemy, or flask-sqlalchemy to understand if this means that requests to the db from multiple threads are safe, but if you’re reading this you’re likely stuck in the baby stages of understanding these concepts too.

Источник

db.create_all() not creating tables in Flask-SQLAclchemy

I am trying to create a database table for a user class model using Flask-SQLAclchemy and Postgres .

My model class.

My app initialisation.

The following info is logged.

3 Answers 3

If you were following the flask quick start minimal application, the command worked by default since the User class was in the same place as the db instance. In your case, however, you will have to import the User class as mentioned in the comments from models import User into your app initialization

As someone in the comments mentioned you are not importing your model into your app initialisation module. You could do that as follows

from models import User

As per previous comments, besides importing the db sqlalchemy object, you have to import manually your model like so

it’s not that bad for small app with couple models to import, but it will be really tedious when it comes to work with medium / large app with many blueprints each one has its own models, so you have to import all of them manually so you can imagine the amount of typing code in the shell without talking about errors (typos, import modules errors ..), the solution is to use Shell Context to load automatically all objects:

now in your shell you can manipulate all objects without any hassle

Источник

SQLAlchemy db.create_all() Error, not creating db

I’ve unsuccessfully search for the solution to this issue. Please help.

When I try to run db.create_all() after importing db from my project, I get

sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) unable to open database file

db.create_all() Traceback (most recent call last): File «/home/kbyrd/anaconda3/envs/flasksite/lib/python3.8/site-packages/sqlalchemy/engine/base.py», line 2339, in _wrap_pool_connect return fn() File «/home/kbyrd/anaconda3/envs/flasksite/lib/python3.8/site-packages/sqlalchemy/pool/base.py», line 364, in connect return _ConnectionFairy._checkout(self) File «/home/kbyrd/anaconda3/envs/flasksite/lib/python3.8/site-packages/sqlalchemy/pool/base.py», line 778, in _checkout fairy = _ConnectionRecord.checkout(pool) File «/home/kbyrd/anaconda3/envs/flasksite/lib/python3.8/site-packages/sqlalchemy/pool/base.py», line 495, in checkout rec = pool._do_get() File «/home/kbyrd/anaconda3/envs/flasksite/lib/python3.8/site-packages/sqlalchemy/pool/impl.py», line 239, in _do_get return self._create_connection() File «/home/kbyrd/anaconda3/envs/flasksite/lib/python3.8/site-packages/sqlalchemy/pool/base.py», line 309, in _create_connection return _ConnectionRecord(self) File «/home/kbyrd/anaconda3/envs/flasksite/lib/python3.8/site-packages/sqlalchemy/pool/base.py», line 440, in init self.__connect(first_connect_check=True) File «/home/kbyrd/anaconda3/envs/flasksite/lib/python3.8/site-packages/sqlalchemy/pool/base.py», line 661, in connect pool.logger.debug(«Error on connect(): %s», e) File «/home/kbyrd/anaconda3/envs/flasksite/lib/python3.8/site-packages/sqlalchemy/util/langhelpers.py», line 68, in exit compat.raise( File «/home/kbyrd/anaconda3/envs/flasksite/lib/python3.8/site-packages/sqlalchemy/util/compat.py», line 178, in raise raise exception File «/home/kbyrd/anaconda3/envs/flasksite/lib/python3.8/site-packages/sqlalchemy/pool/base.py», line 656, in __connect connection = pool._invoke_creator(self) File «/home/kbyrd/anaconda3/envs/flasksite/lib/python3.8/site-packages/sqlalchemy/engine/strategies.py», line 114, in connect return dialect.connect(*cargs, **cparams) File «/home/kbyrd/anaconda3/envs/flasksite/lib/python3.8/site-packages/sqlalchemy/engine/default.py», line 493, in connect return self.dbapi.connect(*cargs, **cparams) sqlite3.OperationalError: unable to open database file

The above exception was the direct cause of the following exception:

Источник

Flask-SQLAlchemy: установка, создание таблиц, добавление записей

На всех наших занятиях этого курса по Flask мы с вами использовали БД SQLite: непосредственно подключались к ней и работали с таблицами через SQL-запросы. Но это не лучшее решение. Для реальных сайтов следует выбирать более функциональные СУБД, рассчитанные на большую нагрузку, когда множество пользователей одновременно могут записывать и читать данные из разных таблиц. Например:

Читайте также:  Можно ли починить диодный прожектор

MySQL, PostgreSQL, Oracle и другие.

Причем, разработчик сайта наперед может не знать с какой именно СУБД будет работать WSGI-приложение. Да и потом, уже в процессе работы, выбор может пасть на другой тип БД. Как в этом случае построить универсальную программу не привязанную к конкретной СУБД? В Python часто для этого используют пакет

который является интерфейсом, построенным по технологии ORM (Object Role Model), позволяющий оперировать таблицами БД как объектами языка Python. Причем этот интерфейс универсален и на уровне WSGI-приложения не привязан к конкретной СУБД.

Так вот, для фреймворка Flask разработано специальное расширение:

которое значительно упрощает настройку и использование самого SQLAlchemy. И о нем пойдет речь на этом занятии.

Вначале, как всегда, его нужно установить. Для этого достаточно выполнить команду:

pip install Flask-SQLAlchemy

и он будет готов к использованию. Далее, я создам новый проект, чтобы нам не разбираться в прежнем коде и не тратить на это время. И, к тому же, так будет проще воспринимать этот материал.

Настройка Flask-SQLAlchemy

Первым делом нужно подключить Flask-SQLAlchemy к нашей программе. Для этого выполним его импорт:

и, затем, после создания экземпляра приложения, создадим в конфигурации специальную константу ‘SQLALCHEMY_DATABASE_URI’:

Эта константа определяет вид используемой СУБД (в данном случае SQLite) и местоположение файла БД (в данном случае – корневой каталог программы). Именно определение этой константы связывает SQLAlchemy с той или иной СУБД. То есть, если в будущем потребуется другая БД, то мы можем просто переопределить эту константу, например, так:

  • postgresql://user:password@localhost/mydatabase
  • mysql://user:password@localhost/mydatabase
  • oracle://user:password@127.0.0.1:1521/mydatabase

и автоматически к программе подключится указанная СУБД. Как видите, все достаточно просто и удобно.

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

Здесь при создании класса передается ссылка на текущее приложение, с которым он будет связан.

Создание таблиц во Flask-SQLAlchemy

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

Так вот, концепция SQLAlchemy заключается в отображении таблиц с помощью Python-классов. То есть, нам достаточно в программе прописать два класса с именами

Users и Profiles

которые бы расширяли базовый класс модели таблиц:

Сначала определим класс Users (порядок не имеет значения, просто иду по рисунку):

Смотрите, мы здесь указываем базовый класс Model, который и превращает класс Users в модель таблицы для SQLAlchemy. А поля таблицы прописываются как обычные переменные, которые ссылаются на специальный класс Column. Этот класс как раз и указывает SQLAlchemy воспринимать эти переменные как поля таблицы. Причем, имя таблицы будет соответствовать имени класса, записанное малыми буквами, а имена переменных – именам полей в этой таблице. Далее, в конструкторе класса Column мы указываем тип поля и дополнительные параметры. Например, поле id будет создаваться как целочисленное и представлять собой главный ключ (то есть, оно будет принимать уникальное значение для каждой записи). Далее, тип String(50) – это строка максимальной длиной в 50 символов, а параметр unique=True означает, что оно должно быть уникальным среди всех записей данной таблицы. Следующее поле psw также является строкой и параметр nullable=False указывает, что оно должно обязательно содержать данные, т.е. пустым быть не может. Наконец, последнее поле date имеет тип datetime для хранения даты и по умолчанию ему присваивается текущая дата, взятая с помощью функции datetime.utcnow. Выше в программе мы ее импортируем:

В конце описания класса идет «магическая» функция __repr__, которая определяет способ отображения класса в консоли. С ее помощью мы будем выводить класс в виде строки формата:

Она здесь прописана для удобства и к функционированию таблиц не имеет отношения.

По аналогии создается вторая таблица Profiles:

Здесь все достаточно очевидно, только дополнительно прописано целочисленное поле user_id, определенное как внешний ключ. Как раз через него можно будет связывать эти две таблицы, то есть, конкретного пользователя с его профайлом.

Вообще, наиболее распространенными типами данными в SQLAlchemy, являются следующие:

  • Integer – целочисленный;
  • String(size) – строка максимальной длиной size;
  • Text – текст (в формате Unicode);
  • DateTime – дата и время представленные в формате объекта datetime;
  • Float – число с плавающей точкой (вещественное);
  • Boolean – логическое значение;
  • LargeBinary – для больших произвольных бинарных данных (например, изображений).

Итак, таблицы определены и теперь можно их создать в БД. Для этого файл (или файлы) БД нужно перенести в какое-либо другое место (или удалить) и, затем, в консоли Python выполнить следующие команды:

from app import db

Здесь app – это название файла, в котором инициализирована переменная db. А метод create_all как раз и создает таблицы, используя классы Users и Profiles.

Добавление записей

Пришло время создать в нашей программе первую функцию представления для регистрации пользователей, где мы могли бы добавлять новые записи в таблицы БД. Вначале пропишем обработчик:

Читайте также:  Рено сценик 2 не работает обдув салона

И определим шаблон register.html на основе базового шаблона layout.html:

Здесь, в принципе, должно быть все вам знакомо: мы описали простую форму с набором полей и кнопкой «Регистрация». Осталось в самом обработчике выполнить добавление записей на основе данных формы:

Сначала, конечно, идет проверка, что данные переданы методом POST, затем, по идее должна быть проверка корректности заполнения полей формы. Но мы пропустим этот шаг, чтобы не перегружать занятие лишней информацией. И после этого, в блоке try осуществляем работу с БД.

В первую очередь мы создаем экземпляр класса Users и через именованные параметры передаем данные из формы. Причем, именованные параметры должны совпадать с именами переменных, объявленных нами ранее. В результате создается объект с данными по email и паролю, который и представляет собой будущую запись в таблице users.

Далее, чтобы ее добавить, происходит обращение к специальному объекту session – сессии БД и в нее добавляется запись с помощью метода add. В качестве параметра этот метод принимает ссылку на объект класса Users. Но эта запись пока еще хранится в сессии – памяти устройства. Физически в таблицу она не занесена. Поэтому, далее, выполняется метод flush, который из сессии перемещает запись в таблицу. Но пока все изменения происходят в памяти устройства и, физически, файл БД остается прежним. Это необходимо, на случай возникновения исключений (ошибок) и «отката» состояния БД к исходному состоянию с помощью метода rollback.

Если ошибок не возникает, то формируется следующий экземпляр класса Profiles с набором данных из формы и дополнительно берется значение u.id, которое сформировалось после метода flush при помещении записи в таблицу users. Вот именно поэтому мы его и вызывали. Далее, запись помещается в сессию и вызывается метод commit, который уже физически меняет файлы БД и сохраняет изменения в таблицах.

В итоге всех этих действий, мы добавили в таблицы users и profiles по одной записи для нового зарегистрированного пользователя, причем, внешний ключ user_id будет ссылаться на id записи из таблицы users.

Видео по теме

Flask #1: Что это такое? Простое WSGI-приложение

Источник

Руководство по SQLAlchemy в Flask

Для работы понадобится python 3.6+, библиотеки SQLAlchemy и Flask. Код урока здесь.
Версии библиотек в файле requirements.txt

В этом материале речь пойдет об основах SQLAlchemy. Создадим веб-приложение на Flask, фреймворке языка Python. Это будет минималистичное приложение, которое ведет учет книг.

С его помощью можно будет добавлять новые книги, читать уже существующие, обновлять и удалять их. Эти операции — создание, чтение, обновление и удаление — также известны как «CRUD» и составляют основу почти всех веб-приложений. О них отдельно пойдет речь в статье.

Но прежде чем переходить к CRUD, разберемся с отдельными элементами приложения, начиная с SQLAlchemy.

Что такое SQLAlchemy?

Стоит отметить, что существует расширение для Flask под названием flask-sqlalchemy , которое упрощает процесс использования SQLAlchemy с помощью некоторых значений по умолчанию и других элементов. Они в первую очередь облегчают выполнение базовых задач. Но в этом материале будет использоваться только чистый SQLAlchemy, чтобы разобраться в его основах без разных расширений.

Как написано на сайте библиотеки «SQLAlchemy — это набор SQL-инструментов для Python и инструмент объектно-реляционного отображения (ORM), который предоставляет разработчикам всю мощь и гибкость SQL».

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

Если еще проще, ORM — это своеобразный переводчик, который переводит код с одного набора абстракций в другой. В этом случае — из Python в SQL.

Есть масса причин, почему стоит использовать ORM, а не вручную сооружать строки SQL. Вот некоторые из них:

  • Ускорение веб-разработки, ведь пропадает необходимость переключаться между написанием кода Python и SQL
  • Устранение повторяющегося кода
  • Оптимизация рабочего процесса и более эффективные запросы к базе данных
  • Абстрагирование системы базы данных, так что переключение между несколькими базами становится более плавным
  • Генерация шаблонного кода для основных операций CRUD

Углубимся еще сильнее.

Зачем использовать ORM, когда можно писать сырой SQL? При написании запросов на сыром SQL, мы передаем их базе данных в виде строк. Следующий запрос написан на сыром SQL:

Нет ничего плохого в использовании чистого SQL для обращения к базам данных, только если вы не сделаете ошибку в запросе. Это может быть, например, опечатка в названии базы, к которой происходит обращение или неправильное название таблицы. Компилятор Python здесь ничем не поможет.

SQLAlchemy — один из множества ORM-инструментов для Python. При работе с маленькими приложения чистый SQL может сработать. Но если это большой сайт с массой данных, такой подход сильнее подвержен ошибкам и просто более сложен.

Создание базы данных с помощью SQLAlchemy

Создадим файл для настройки базы данных. Можете назвать его как угодно, но пусть это будет database_setup.py .

В верхней части файла импортируем все необходимые модули для настройки и создания баз данных. Для определения колонок в таблицах импортируем Column, ForeignKey, Integer и String .

Читайте также:  Почему не работает помощник осаго

Далее импортируем расширение declarative_base . Base = declarative_base() создает базовый класс для определения декларативного класса и присваивает его переменной Base .

Согласно документации declarative_base() возвращает новый базовый класс, который наследуют все связанные классы. Это таблица, mapper() и объекты класса в пределах его определения.

Далее создаем экземпляр класса create_engine , который указывает на базу данных с помощью engine = create_engine(‘sqlite:///books-collection.db’) . Можно назвать базу данных как угодно, но здесь пусть будет books-collection .

Последний этап настройки — добавление Base.metadata.create_all(engine) . Это добавит классы (напишем их чуть позже) в виде таблиц созданной базы данных.

После настройки базы данных создаем классы. В SQLAlchemy классы являются объектно-ориентированными или декларативными представлениями таблицы в базе данных.

Для этого руководства достаточно одной таблицы: Book . Она будет содержать 4 колонки: id , title , author и genre . Integer и String используются для определения типа значений, которые будут храниться в колонках. Колонка с названием, именем автора и жанром — это строки, а id — число.

Есть много атрибутов класса, которые используются для определения колонок, но рассмотрим уже использованные:

  1. primary_key : при значении True указывает на значение, используемое для идентификации каждой уникальной строки таблицы.
  2. String(250) : String — тип значения, а значение в скобках — максимальная длина строки.
  3. Integer : указывает тип значения (целое число).
  4. nullable : если False , это значит, что для создания строки обязательно должно быть значение .

На этом процесс настройки заканчивается. Если сейчас использовать команду python database_setup.py в командной строке, будет создана пустая база данных books-collection.db . Теперь можно наполнять ее данными и пробовать обращаться.

CRUD с SQLAlchemy на примерах

В начале кратко была затронута тема операций CRUD. Пришло время их использовать.

Создадим еще один файл и назовем его populate.py (или любым другим именем).

В первую очередь импортируем все зависимости и некоторые классы из файла database_setup.py .

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

Что бы создать соединение между определениями класса и таблицами в базе данных, используем команду Base.metadata.bind .

Для создания, удаления, чтения или обновления записей в базе данных SQLAlchemy предоставляет интерфейс под названием Session . Для выполнения запросов необходимо добавлять и фиксировать (делать комит) запроса. Используем метод flush() . Он переносит изменения из памяти в буфер транзакции базы данных без фиксации изменения.

CREATE:

Стандартный процесс создания записи следующий:

Создать первую книгу можно с помощью следующей команды:

В зависимости от того, что нужно прочитать, используются разные функции. Рассмотрим два варианты их использования в приложении.

session.query(Book).all() — вернет список всех книг

session.query(Book).first() — вернет первый результат или None , если строки нет

UPDATE:

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

  1. Найти запись
  2. Сбросить значения
  3. Добавить новую запись
  4. Зафиксировать сессию в базе данных (сделать комит)

Если еще не заметили, в записи bookOne есть ошибка. Книгу «Чистый Python» написал Дэн Бейдер, а не «Дэн Бейде». Обновим имя автора с помощью 4 описанных шагов.

Для поиска записи используется filter() , который фильтрует запросы на основе атрибутов записей. Следующий запрос выдаст книгу с id=1 (то есть, «Чистый Python»)

Чтобы сбросить и зафиксировать имя автора, нужны следующие команды:

Можно использовать all() , one() или first() для поиска записи в зависимости от ожидаемого результата. Но есть несколько нюансов, о которых важно помнить.

  1. all() — возвращает результаты запроса в виде списка
  2. one() — возвращает один результат или вызывает исключение. Вызовет исключение sqlaclhemy.orm.exc.NoResultFoud , если результат не найден или sqlaclhemy.orm.exc.NoResultFoud , если были возвращены несколько результатов
  3. first() — вернет первый результат запроса или None , если он не содержит строк, но без исключения

DELETE:

Удаление значений из базы данных — это почти то же самое, что и обновление:

  1. Находим запись
  2. Удаляем запись
  3. Фиксируем сессию

Теперь когда база данных настроена и есть базовое понимание CRUD-операций, пришло время написать небольшое приложение Flask. Но в сам фреймворк не будем углубляться. О нем можно подробнее почитать в других материалах.

Создадим новый файл app.py в той же папке, что и database_setup.py и populate.py . Затем импортируем необходимые зависимости.

Наконец, нужно создать шаблоны: books.html , newBook.html , editBook.html и deleteBook.html . Для этого создадим папку с шаблонами во Flask templates на том же уровне, где находится файл app.py . Внутри него создадим четыре файла.

Если запустить приложение app.py и перейти в браузере на страницу https://localhost:4996/books, отобразится список книг. Добавьте несколько и если все работает, это выглядит вот так:

Расширение приложения и выводы

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

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

Источник

Оцените статью