Search code examples
flaskherokuredissqlalchemyrq

This is not work Flask Rq Queue with SqlAlchemy database table


I Have a Flask project. Process are work normal. Database is PostgreSql. Everything is working on this Database. But when I Can use Python Rq I dont reach tables with SqlAlchemy. My project is on heroku. How can i solve this problem.

Note:( queuing operations are working normally except database)

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) code Error result

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/.

Solution

  • The error is not with redis or database. The error says

    No application found. Either work inside a view function or push an application context

    RuntimeError: Working outside of application context.

    This typically means that you attempted to use functionality that needed to interface with the current application object in some way. To solve this, set up an application context with app.app_context().

    In your case you have to use

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

    For this you need to import your app, In your case, It is main as I see the route \test so you have to use main in place of app, with main.app_context():