【问题标题】:Assertion error with flask and SQL Alchemy烧瓶和 SQL Alchemy 的断言错误
【发布时间】:2020-11-25 18:45:23
【问题描述】:

我有以下烧瓶结构:

使用以下代码:

init.py

from press_app.views import app
from press_app import models

# Connect sqlalchemy to app
models.db.init_app(app)

@app.cli.command()
def init_db():
    models.init_db()

models.py

from flask_sqlalchemy import SQLAlchemy
import logging as lg
from press_app.views import app

# Create database connection object
db = SQLAlchemy(app)

class Content(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    author = db.Column(db.String(100), nullable=True)
    content = db.Column(db.String(700), nullable=True)
    description = db.Column(db.String(700), nullable=True)
    publishedAt = db.Column(db.DateTime())
    source = db.Column(db.String(100), nullable=True)
    title = db.Column(db.String(200), nullable=True)
    url = db.Column(db.String(1000), nullable=True)
    urlToImage = db.Column(db.String(1000), nullable=True)

    def __init__(self, author, content, description, publishedAt, source, title, url, urlToImage):
        self.author = author
        self.content = content
        self.description = description
        self.publishedAt = publishedAt
        self.source = source
        self.title = title
        self.url = url
        self.urlToImage = urlToImage

db.create_all()

def init_db():
    db.drop_all()
    db.create_all()
    db.session.commit()
    lg.warning('Database initialized!')

views.py

from flask import Flask, render_template
from press_app.models import Content

app = Flask(__name__)

# Config options - Make sure you created a 'config.py' file.
app.config.from_object('config')
# To get one variable, tape app.config['MY_VARIABLE']

@app.route('/')
def index():
    last_article = Content.query.order_by(Content.id.desc()).first()
    last_id = last_article.id

    # Derniers titres
    title1 = Content.query.get(last_id).title
    title2 = Content.query.get(last_id - 1).title

    return render_template("index3.html", titre1 = title1)

if __name__ == "__main__":
    app.run()

config.py

import os

basedir = os.path.abspath(os.path.dirname(__file__))
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'app.db')

run.py

from press_app import app
if __name__ == "__main__":
    app.run()

由于以下错误消息:

ImportError: cannot import name 'app' from partially initialized module 'press_app.views' (most likely due to a circular import) 

我选择直接在我的函数中移动views.py文件中的一个导入,如下:

views.py,第二版

from flask import Flask, render_template

app = Flask(__name__)

# Config options - Make sure you created a 'config.py' file.
app.config.from_object('config')
# To get one variable, tape app.config['MY_VARIABLE']

@app.route('/')
def index():
    from press_app.models import Content

    last_article = Content.query.order_by(Content.id.desc()).first()
    last_id = last_article.id

    # Derniers titres
    title1 = Content.query.get(last_id).title
    title2 = Content.query.get(last_id - 1).title

    return render_template("index3.html", titre1 = title1)

if __name__ == "__main__":
    app.run()

但是,我遇到了一个新的错误消息(错误 500),我无法解决,尽管我阅读了许多有关它的文档和 stackoverflow 消息。

AssertionError: The sqlalchemy extension was not registered to the current application.  Please make sure to call init_app() first.

我该如何解决这种情况?

【问题讨论】:

    标签: python python-3.x flask sqlalchemy flask-sqlalchemy


    【解决方案1】:

    这个问题是因为你在另一个文件中初始化模型,在另一个文件中初始化flask app,你的app需要在sqlalchemy对象之前初始化,这样你才能使用它。

    所以你的文件应该是这样的。

    views.py

    from flask import Flask, render_template
    from models import db
    
    app = Flask(__name__)
    
    # Config options - Make sure you created a 'config.py' file.
    app.config.from_object('config')
    # To get one variable, tape app.config['MY_VARIABLE']
    db.init_app(app)
    with app.app_context():
        db.create_all()
        db.session.commit()
    
    
    @app.route('/')
    def index():
        from models import Content
    
        last_article = Content.query.order_by(Content.id.desc()).first()
        last_id = last_article.id
    
        # Derniers titres
        title1 = Content.query.get(last_id).title
        title2 = Content.query.get(last_id - 1).title
    
        return render_template("index3.html", titre1 = title1)
    
    
    if __name__ == "__main__":
        app.run()
    

    models.py

    from flask_sqlalchemy import SQLAlchemy
    import logging as lg
    
    # Create database connection object
    db = SQLAlchemy()
    
    class Content(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        author = db.Column(db.String(100), nullable=True)
        content = db.Column(db.String(700), nullable=True)
        description = db.Column(db.String(700), nullable=True)
        publishedAt = db.Column(db.DateTime())
        source = db.Column(db.String(100), nullable=True)
        title = db.Column(db.String(200), nullable=True)
        url = db.Column(db.String(1000), nullable=True)
        urlToImage = db.Column(db.String(1000), nullable=True)
    
        def __init__(self, author, content, description, publishedAt, source, title, url, urlToImage):
            self.author = author
            self.content = content
            self.description = description
            self.publishedAt = publishedAt
            self.source = source
            self.title = title
            self.url = url
            self.urlToImage = urlToImage
    
    
    def init_db():
        db.drop_all()
        db.create_all()
        db.session.commit()
        lg.warning('Database initialized!')
    

    【讨论】:

    • 你能解释一下你在views.py中添加的行吗?
    • 所以在你的代码中,问题是你在初始化数据库时没有初始化你的烧瓶应用程序db = SQLAlchemy(app),所以我们所做的就是创建空的 sqlahcemy 实例,然后初始化烧瓶应用程序,然后用它来初始化数据库。同样在烧瓶中,如果您需要在控制器方法之外进行任何操作,则烧瓶需要传递上下文。这条线就是with app.app_context():
    猜你喜欢
    • 2019-03-19
    • 2019-04-27
    • 2015-02-16
    • 1970-01-01
    • 1970-01-01
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多