与 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 相关的问题的主要内容,如果未能解决你的问题,请参考以下文章

flask-migrate

11.14

简单分析Flask 数据库迁移详情

连接mysql数据库,创建用户模型

通过用户模型,对数据库进行增删改查操作。

flask 数据库连接问题