与 db.create_all() SQLAlchemy Python3.6 相关的问题
Posted
技术标签:
【中文标题】与 db.create_all() SQLAlchemy Python3.6 相关的问题【英文标题】:Issue related with db.create_all() SQLAlchemy Python3.6 【发布时间】:2022-01-09 08:01:03 【问题描述】:总结一下我的问题,我尝试使用 SQLAlchemy 命令 db.create_all() 生成我的 PostgreSQL 数据库表,它返回以下错误:
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)
这次执行的结果是NOTHING。数据库内部绝对没有发生任何事情,我 100% 确定我的运行和数据库之间存在连接,但没有生成表或任何类型的错误。
在所有替代方案中,我认为最合理的是通过 python 终端运行创建,但是,当我运行我的应用程序时,我遇到了 powershell 已经包含的环境变量的问题,但它不能帮助我初始化来自终端的数据库。
有人可以在某个方向给我一些提示或帮助吗?
【问题讨论】:
文档似乎建议从 Python REPL 或>>>
提示符创建,这是你在做什么?参考:flask-sqlalchemy.palletsprojects.com/en/2.x/quickstart
似乎还有另一种方法:app = Flask(__name__); db = SQLAlchemy(app)
。你的 app.py 中有这个吗?参考:flask-sqlalchemy.palletsprojects.com/en/2.x/api/#configuration
感谢您的回复@mechanical_meat。我尝试应用使用 db = SQLAlchemy(app) 初始化对象 db 的方法。但是,在此过程中没有创建任何表。在第一条评论中,您指出了我目前遇到的相同问题,我无法通过 python 终端分配环境变量。感谢您的帮助。
如果您需要设置环境变量,您应该研究如何为您正在使用的操作系统执行此操作。然后在 Python 中,您可以使用 os
模块访问它,我认为调用是:os.get_env('YOUR_ENVIRONMENT_VARIABLE_NAME_HERE')
。
再次感谢您的帮助@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 中并且自动创建表。
我再次感谢所有费心阅读此线程的人,如果有人有更优雅的解决方案,我将很乐意深入分析它。如果这可以帮助其他人找到一个很棒的解决方案。
【讨论】:
以上是关于与 db.create_all() SQLAlchemy Python3.6 相关的问题的主要内容,如果未能解决你的问题,请参考以下文章