Проблема, связанная с db.create_all() SQLAlchemy Python3.6

python-3.x #virtualenv #flask-sqlalchemy

#python-3.x #virtualenv #flask-sqlalchemy

Вопрос:

Подводя итог моей проблеме, я пытаюсь сгенерировать таблицы базы данных PostgreSQL с помощью команды SQLAlchemy db.create_all(), и она возвращает следующую ошибку:

 RuntimeError: No application found. Either work inside a view function or push an application context. See http://flask-sqlalchemy.pocoo.org/contexts/.
 

Я, конечно, следил за документацией и потоками на этой платформе и пробовал разные альтернативы:

 from app import db, create_app
db.create_all()
 

Этот подход по-прежнему терпит неудачу с тем же сообщением. Другой альтернативой было включить функцию create_app в функцию create_all(), чтобы у нее был правильный контекст.

 db.create_all(app=create_app())
 

Это вызвало новую ошибку, потому что при выполнении функции create_app() ей нужны переменные среды (я не знаю, как включить переменные через терминал python).

     db.init_app(app)
with app.app_context():
    db.create_all()
migrate.init_app(app, db)
mail.init_app(app) 
 

Результат этого выполнения — НИЧТО. Внутри базы данных абсолютно ничего не происходит, я на 100% уверен, что между моим запуском и моей базой данных есть связь, но таблица или какая-либо ошибка не генерируется.

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

Может ли кто-нибудь дать мне подсказку или помочь в каком-либо направлении?

Комментарии:

1. Документация, похоже, рекомендует создавать из Python REPL или >>> приглашения, это то, что вы делаете? Ссылка: flask-sqlalchemy.palletsprojects.com/en/2.x/quickstart

2. Кажется, есть другой способ сделать это : app = Flask(__name__); db = SQLAlchemy(app) . Есть ли у вас это в вашем app.py ? Ссылка: flask-sqlalchemy.palletsprojects.com/en/2.x/api/#configuration

3. Спасибо за ваш ответ @mechanical_meat. Я пытаюсь применить подход инициализации объекта db с помощью db = SQLAlchemy(app). Однако в процессе не было создано ни одной таблицы. В первом комментарии вы указываете на ту же проблему, что и у меня в настоящее время, я не могу назначать переменные среды через терминал python. Спасибо за вашу помощь.

4. Если вам нужна переменная среды, вам следует изучить, как это сделать для используемой вами ОС. Затем в Python вы можете получить к нему доступ с os помощью модуля, я думаю, что вызов выполняется следующим образом: os.get_env('YOUR_ENVIRONMENT_VARIABLE_NAME_HERE') .

5. Еще раз спасибо за вашу помощь @mechanical_meat. Моя разработка работает (без создания таблиц базы данных) при добавлении переменных среды: $env:FLASK_APP="app" $env:APP_ENV="development" $env:APP_SETTINGS_MODULE="config.dev" я попытался добавить жестко заданную переменную среды в коде и вызов, как вы мне сказали, со следующим сообщением, которое выдает ошибку, не найдя переменную FLASK_ENV: from app import db, create_app db.create_all(app=create_app("config.dev")) Еще раз спасибо!

Ответ №1:

Приветствую всех, кто интересовался этой темой, и особую благодарность mechanical_meat за его поддержку и помощь.

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

 ├── entrypoint.py
├── config
├── app
│   ├── __init__.py
│   │   └── models.py
│   ├── module 1
│   │   └── models.py
│   ├── module 2
│   ├── module N
│   │   └── models.py
 

На случай, если мне понадобится запустить мое приложение, я активировал свою виртуальную среду и добавил необходимые переменные среды (FLASK_ENV, FLASK_APP или APP_SETTINGS_MODULE).

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

 from flask import send_from_directory
import os
from app import create_app

settings_module = os.getenv('APP_SETTINGS_MODULE')
app = create_app(settings_module)

if __name__ == '__main__':
    app.run(debug=True)
 

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

 from flask import Flask
from flask_login import LoginManager
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SECRET_KEY'] = 'SECRET'
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:...'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

login_manager = LoginManager(app)
login_manager.login_view = "login"
db = SQLAlchemy(app)

from models_db import User, Task, History
 

Другой файл содержит объявление классов для правильной загрузки столбцов. И с этим решением генерация таблиц базы данных сработала, единственным дополнительным изменением было изменение переменной среды из app в мой новый класс, который отвечает за создание БД. Это необходимо, потому что моя цель состоит в том, чтобы его можно было включить в dockerfile, и таблицы создаются автоматически.

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