0

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

注意:(队列操作正常工作,除了数据库)

初始化.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

工人.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.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", line 1008, 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", line 1031, 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", line 749, 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", line 772, 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", line 43, 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", line 552, 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", line 129, 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", line 1010, 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", line 4089, 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", line 174, 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", line 1042, 
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/.
4

2 回答 2

0

我这样做是为了解决。请注意那些遇到相同错误的人的历史:) 魔术代码“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
于 2021-07-09T08:16:24.713 回答
0

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

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

RuntimeError:在应用程序上下文之外工作。

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

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

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

为此,您需要导入您的应用程序,在您的情况下,main就像我看到的路线一样\test,您必须使用main代替appwith main.app_context():

于 2021-07-09T02:57:05.733 回答