SQLAlchemy 3上使用flask-shell或Python shell创建表的解决方案[重复]

问题描述 投票:0回答:1

所以最近我作为一个新手用 Flask 启动了一个 Python 项目,想要创建一个“注册和登录页面”,一切都很顺利。但是,当我在数据库中创建一个存储用户名和密码的表时,我收到错误,并且不会创建该表。

我的主题更详细的是,当我进入 bash 并输入此命令时,我收到此错误

我从 python3 的终端开始 我从应用程序导入数据库,因此它导入变量db = SQLAlchemy 之后我输入 db.create_all()

我收到此错误

sk@Aress-MacBook-Air FPLPage % python3
Python 3.12.1 (v3.12.1:2305ca5144, Dec  7 2023, 17:23:38) [Clang 13.0.0 (clang-1300.0.29.30)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from app import db
>>> db.create_all()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/flask_sqlalchemy/extension.py", line 900, in create_all
    self._call_for_binds(bind_key, "create_all")
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/flask_sqlalchemy/extension.py", line 871, in _call_for_binds
    engine = self.engines[key]
             ^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/flask_sqlalchemy/extension.py", line 687, in engines
    app = current_app._get_current_object()  # type: ignore[attr-defined]
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/werkzeug/local.py", line 508, in _get_current_object
    raise RuntimeError(unbound_message) from None
RuntimeError: Working outside of application context.

This typically means that you attempted to use functionality that needed
the current application. To solve this, set up an application context
with app.app_context(). See the documentation for more information.

我还将上传 app.py 代码,以便您可以更好地理解

from flask import Flask, render_template, url_for, redirect
from flask_sqlalchemy import SQLAlchemy
from flask_login import UserMixin
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import InputRequired, Length, ValidationError
from flask_bcrypt import Bcrypt

app = Flask(__name__)
bcrypt = Bcrypt(app)

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'
app.config['SECRET_KEY'] ="b9ZHtEpIeiKHuM8"
db = SQLAlchemy(app)

class User(db.Model, UserMixin): ##Database Table for User
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20), nullable=False, unique=True)
    password = db.Column(db.String(50), nullable=False)


class RegisterForm(FlaskForm):

    username = StringField(validators=[InputRequired(),Length(min = 4, max = 20)],render_kw={"placeholder": "Username"})

    password = StringField(validators=[InputRequired(),Length(min = 4, max = 20)],render_kw={"placeholder": "Password"})

    
    submit = SubmitField("Register")



class LoginForm(FlaskForm):

    username = StringField(validators=[InputRequired(),Length(min = 4, max = 20)],render_kw={"placeholder": "Username"})

    password = StringField(validators=[InputRequired(),Length(min = 4, max = 20)],render_kw={"placeholder": "Password"})

    
    submit = SubmitField("Login")


def validate_username(self,username):
    existing_user_username = User.query.filter_by(
        username = username.data).first()
    

    if existing_user_username:
        raise ValidationError(
            "The Username is already in use.Try to think another one:)"
        )

我创建了一个 models.py 并使用 Flask 和 SQLAlchemy 以及类移动了代码 但这些都不起作用。所以现在我不知道我做错了什么

sqlite flask flask-sqlalchemy database-table
1个回答
0
投票

经过大量搜索后,我找到了如何让它发挥作用

解决方案:

从 Flask-SQLAlchemy 3.0 开始,对 db.engine(和 db.session)的所有访问都需要活动的 Flask 应用程序上下文。

db.create_all 使用 db.engine ,因此它需要应用程序上下文。

with app.app_context():
    db.create_all()

当 Flask 处理请求或运行 CLI 命令时,会自动推送上下文。您只需手动推一推即可 在这些情况之外,例如在设置应用程序时。

您也可以在 shell 中手动调用它,而不是在代码中调用 create_all。使用flask shell启动Python 已具有应用程序上下文并导入数据库对象的 shell。

$ flask shell
>>> db.create_all()

或者如果使用普通的 Python shell,则手动推送上下文。

$ python
>>> from project import app, db
>>> app.app_context().push()
>>> db.create_all()
© www.soinside.com 2019 - 2024. All rights reserved.