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/quickstart2. Кажется, есть другой способ сделать это :
app = Flask(__name__); db = SQLAlchemy(app)
. Есть ли у вас это в вашем app.py ? Ссылка: flask-sqlalchemy.palletsprojects.com/en/2.x/api/#configuration3. Спасибо за ваш ответ @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, и таблицы создаются автоматически.
Я еще раз выражаю свою благодарность всем вам, кто потрудился прочитать эту тему, если у кого-нибудь есть более элегантное решение, я буду рад подробно проанализировать его. Если это может помочь кому-то другому найти решение, это было бы здорово.