这对带有 SqlAlchemy 数据库表的 Flask Rq 队列不起作用

问题描述

我有一个 Flask 项目。过程工作正常。数据库是 Postgresql。一切都在这数据库上工作。但是当我可以使用 Python Rq 时,我无法使用 sqlAlchemy 访问表。我的项目在heroku上。我该如何解决这个问题。

注意:(除数据库外,排队操作正常)

init.py

from flask import Flask
from flask_sqlalchemy import sqlAlchemy
from flask_login import LoginManager

import os
import redis
from rq import Queue
from worker import conn
#from models import User,Processed,Wallet,LogsRecord

 

# init sqlAlchemy so we can use it later in our models
db = sqlAlchemy()
q = Queue(connection=conn)
 
 

def create_app():
    app = Flask(__name__) # creates the Flask instance,__name__ is the name of the current Python module
  
    app.config['SECRET_KEY'] = '****' # it is used by Flask and extensions to keep data safe
    #app.config['sqlALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite' #it is the path where the sqlite database file will be saved
      
    app.config['sqlALCHEMY_DATABASE_URI'] = 'postgresql://*****@e****.compute**.m**.com:5432/**' 

    #app.config['sqlALCHEMY_DATABASE_URI'] = 'postgresql://postgres:*****' #local
    
    app.config['sqlALCHEMY_TRACK_MODIFICATIONS'] = True # deactivate Flask-sqlAlchemy track modifications



    db.init_app(app) # Initialiaze sqlite database
   
    # The login manager contains the code that lets your application and Flask-Login work together
    login_manager = LoginManager() # Create a Login Manager instance
    login_manager.login_view = 'auth.login' # define the redirection path when login required and we attempt to access without being logged in
    login_manager.init_app(app) # configure it for login
    from models import User
    @login_manager.user_loader
    def load_user(user_id): #reload user object from the user ID stored in the session
        # since the user_id is just the primary key of our user table,use it in the query for the user
        return User.query.get(int(user_id))
    # blueprint for auth routes in our app
    # blueprint allow you to orgnize your flask app
    from auth import auth as auth_blueprint
    app.register_blueprint(auth_blueprint)
    # blueprint for non-auth parts of app
    from main import main as main_blueprint
    app.register_blueprint(main_blueprint)

    app.register_blueprint()

    
    
    return app

Worker.py

import os

import redis
from rq import Worker,Queue,Connection
 
listen = ['high','default','low']

redis_url = os.getenv('REdisTOGO_URL','redis://localhost:6379')

conn = redis.from_url(redis_url)

if __name__ == '__main__':
    with Connection(conn):
        worker = Worker(map(Queue,listen))
        worker.work()

Main.py

@main.route('/test') # profile page that return 'profile'
def test():

    if request.args.get("n"):
     
        job= q.enqueue(background_task,request.args.get("n"))
   

    return render_template('test.html',veri=job.get_id)


def background_task(n):
    
    user_check = User.query.get(1)
    if(user_check):
        n=int(n)
        email=user_check.email
        start = time.time()
        for i in range(n):
            print("sayı sayıyor:",i," Kul:",email)
            time.sleep(1)
        end = time.time()     
        sure = (end-start)
    return f"Son Sayı {n} İşlem şu kadar sürdü {sure}"

bash (heroku logs --tail) 代码错误结果

2021-07-08T22:09:07.034922+00:00 app[worker.1]: 22:09:07 Traceback (most recent call last):
2021-07-08T22:09:07.034947+00:00 app[worker.1]: File "/app/.heroku/python/lib/python3.9/site-packages/sqlalchemy/util/_collections.py",line 1008,in __call__
2021-07-08T22:09:07.034949+00:00 app[worker.1]: return self.registry[key]
2021-07-08T22:09:07.034949+00:00 app[worker.1]: KeyError: <greenlet.greenlet object at 0x7f60ec8853b0 (otid=0x7f60ec890f80) current active started main>
2021-07-08T22:09:07.034951+00:00 app[worker.1]:
2021-07-08T22:09:07.034952+00:00 app[worker.1]: During handling of the above exception,another exception occurred:
2021-07-08T22:09:07.034952+00:00 app[worker.1]:
2021-07-08T22:09:07.034952+00:00 app[worker.1]: Traceback (most recent call last):
2021-07-08T22:09:07.034953+00:00 app[worker.1]: File "/app/.heroku/python/lib/python3.9/site-packages/rq/worker.py",line 1031,in perform_job  
2021-07-08T22:09:07.034953+00:00 app[worker.1]: rv = job.perform()
2021-07-08T22:09:07.034954+00:00 app[worker.1]: File "/app/.heroku/python/lib/python3.9/site-packages/rq/job.py",line 749,in perform
2021-07-08T22:09:07.034955+00:00 app[worker.1]: self._result = self._execute()
2021-07-08T22:09:07.034955+00:00 app[worker.1]: File "/app/.heroku/python/lib/python3.9/site-packages/rq/job.py",line 772,in _execute
2021-07-08T22:09:07.034956+00:00 app[worker.1]: result = self.func(*self.args,**self.kwargs)
2021-07-08T22:09:07.034957+00:00 app[worker.1]: File "/app/main.py",line 43,in background_task
2021-07-08T22:09:07.034957+00:00 app[worker.1]: user_check = User.query.get(1)
2021-07-08T22:09:07.034958+00:00 app[worker.1]: File "/app/.heroku/python/lib/python3.9/site-packages/flask_sqlalchemy/__init__.py",line 552,in __get__
2021-07-08T22:09:07.034958+00:00 app[worker.1]: return type.query_class(mapper,session=self.sa.session())
2021-07-08T22:09:07.034959+00:00 app[worker.1]: File "/app/.heroku/python/lib/python3.9/site-packages/sqlalchemy/orm/scoping.py",line 129,in __call__
2021-07-08T22:09:07.034959+00:00 app[worker.1]: return self.registry()
2021-07-08T22:09:07.034960+00:00 app[worker.1]: File "/app/.heroku/python/lib/python3.9/site-packages/sqlalchemy/util/_collections.py",line 1010,in __call__
2021-07-08T22:09:07.034960+00:00 app[worker.1]: return self.registry.setdefault(key,self.createfunc())
2021-07-08T22:09:07.034961+00:00 app[worker.1]: File "/app/.heroku/python/lib/python3.9/site-packages/sqlalchemy/orm/session.py",line 4089,in 
__call__
2021-07-08T22:09:07.034961+00:00 app[worker.1]: return self.class_(**local_kw)
2021-07-08T22:09:07.034961+00:00 app[worker.1]: File "/app/.heroku/python/lib/python3.9/site-packages/flask_sqlalchemy/__init__.py",line 174,in __init__
2021-07-08T22:09:07.034962+00:00 app[worker.1]: self.app = app = db.get_app()
2021-07-08T22:09:07.034962+00:00 app[worker.1]: File "/app/.heroku/python/lib/python3.9/site-packages/flask_sqlalchemy/__init__.py",line 1042,in get_app
2021-07-08T22:09:07.034963+00:00 app[worker.1]: raise RuntimeError(
2021-07-08T22:09:07.034964+00:00 app[worker.1]: RuntimeError: No application found. Either work inside a view function or push an application context. See http://flask-sqlalchemy.pocoo.org/contexts/.
2021-07-08T22:09:07.034964+00:00 app[worker.1]: Traceback (most recent call last):
2021-07-08T22:09:07.034965+00:00 app[worker.1]: File "/app/.heroku/python/lib/python3.9/site-packages/sqlalchemy/util/_collections.py",in __call__
2021-07-08T22:09:07.034965+00:00 app[worker.1]: return self.registry[key]
2021-07-08T22:09:07.034965+00:00 app[worker.1]: KeyError: <greenlet.greenlet object at 0x7f60ec8853b0 (otid=0x7f60ec890f80) current active started main>
2021-07-08T22:09:07.034966+00:00 app[worker.1]:
2021-07-08T22:09:07.034966+00:00 app[worker.1]: During handling of the above exception,another exception occurred:
2021-07-08T22:09:07.034967+00:00 app[worker.1]:
2021-07-08T22:09:07.034967+00:00 app[worker.1]: Traceback (most recent call last):
2021-07-08T22:09:07.034967+00:00 app[worker.1]: File "/app/.heroku/python/lib/python3.9/site-packages/rq/worker.py",in perform_job  
2021-07-08T22:09:07.034968+00:00 app[worker.1]: rv = job.perform()
2021-07-08T22:09:07.034968+00:00 app[worker.1]: File "/app/.heroku/python/lib/python3.9/site-packages/rq/job.py",in perform
2021-07-08T22:09:07.034969+00:00 app[worker.1]: self._result = self._execute()
2021-07-08T22:09:07.034969+00:00 app[worker.1]: File "/app/.heroku/python/lib/python3.9/site-packages/rq/job.py",in _execute
2021-07-08T22:09:07.034969+00:00 app[worker.1]: result = self.func(*self.args,**self.kwargs)
2021-07-08T22:09:07.034970+00:00 app[worker.1]: File "/app/main.py",in background_task
2021-07-08T22:09:07.034970+00:00 app[worker.1]: user_check = User.query.get(1)
2021-07-08T22:09:07.034971+00:00 app[worker.1]: File "/app/.heroku/python/lib/python3.9/site-packages/flask_sqlalchemy/__init__.py",in __get__
2021-07-08T22:09:07.034971+00:00 app[worker.1]: return type.query_class(mapper,session=self.sa.session())
2021-07-08T22:09:07.034972+00:00 app[worker.1]: File "/app/.heroku/python/lib/python3.9/site-packages/sqlalchemy/orm/scoping.py",in __call__
2021-07-08T22:09:07.034972+00:00 app[worker.1]: return self.registry()
2021-07-08T22:09:07.034972+00:00 app[worker.1]: File "/app/.heroku/python/lib/python3.9/site-packages/sqlalchemy/util/_collections.py",in __call__
2021-07-08T22:09:07.034973+00:00 app[worker.1]: return self.registry.setdefault(key,self.createfunc())
2021-07-08T22:09:07.034973+00:00 app[worker.1]: File "/app/.heroku/python/lib/python3.9/site-packages/sqlalchemy/orm/session.py",in 
__call__
2021-07-08T22:09:07.034974+00:00 app[worker.1]: return self.class_(**local_kw)
2021-07-08T22:09:07.034974+00:00 app[worker.1]: File "/app/.heroku/python/lib/python3.9/site-packages/flask_sqlalchemy/__init__.py",in __init__
2021-07-08T22:09:07.034974+00:00 app[worker.1]: self.app = app = db.get_app()
2021-07-08T22:09:07.034981+00:00 app[worker.1]: File "/app/.heroku/python/lib/python3.9/site-packages/flask_sqlalchemy/__init__.py",in get_app
2021-07-08T22:09:07.034982+00:00 app[worker.1]: raise RuntimeError(
2021-07-08T22:09:07.034982+00:00 app[worker.1]: RuntimeError: No application found. Either work inside a view function or push an application context. See http://flask-sqlalchemy.pocoo.org/contexts/.

解决方法

该错误与 redis 或数据库无关。错误说

未找到应用程序。在视图函数中工作或推送应用程序上下文

运行时错误:在应用程序上下文之外工作。

这通常意味着您尝试使用以下功能 需要以某种方式与当前应用程序对象交互。 要解决此问题,请使用 app.app_context() 设置应用程序上下文。

在你的情况下,你必须使用

with app.app_context():
    user_check = User.query.get(1)
if(user_check):
    [...]

为此,您需要导入您的应用程序,就您而言,它是 main,因为我看到路线 \test,因此您必须使用 main 代替 {{1} },app

,

我这样做是为了解决问题。请注意那些遇到相同错误的人的历史记录:) 魔术代码“app.app_context().push()”

app = create_app()  
**app.app_context().push()**
if __name__ == '__main__':
    db.create_all(app=create_app())
    app.run(debug=True) # run the flask app on debug mode