Open bnewman70 opened 1 year ago
hey @bnewman70, so if I understand you correctly, the error is only coming up in jobs that have the @login_required
decorator on them as well? Can you share code where the decorator is added?
the jobs don't have the @login_required decorator, the routes do.
Using Flask-login 0.5.0
When I try to access an object under the current__user that's when the error occurs, but only after I call scheduler.run_job and the job runs within the block
with scheduler.app.app_context():
If I do a run_job in a test job that does not run within a with scheduler.app.app_context(): block, the object under my current_user is correctly pulled from the database with no error.
Heres some code blocks in order of execution:
Route for a page that lists all jobs and allows user to perform actions, like pause, resume and run now. Note i added a current_user.profile call as a work around to avoiding the error @blueprint.route('/jobs', methods=['GET','POST']) @login_required def jobs(): action = request.args.get('action') jobs = scheduler.get_jobs() print('got jobs',len(jobs)) if action == 'pause': print('pausing job') scheduler.pause_job(request.args.get('jid')) flash('Job paused',category='success') elif action == 'resume': scheduler.resume_job(request.args.get('jid')) flash('Job Resumed',category='success') elif action == 'run_now':
print(current_user.profile)
scheduler.run_job(request.args.get('jid'))
flash('Job Started',category='success')
example job, triggering the detached instance error. If I remove with scheduer.app.app_context(), the error does not occur @scheduler.task("interval",id=hello_world,seconds=60,max_instances=1,start_date="2000-01-01 12:19:00") def hello_world(): with scheduler.app.app_context(): print("hello world job")
In my template I show the user profile image from the current_user.profile in the header of each page.. this triggers the error. I an guessing I only see it on run_now because this page immediately reloads after run. Other pages may not be refreshed during a job run. {% if current_user.profile %} {% for user in current_user.profile %}
{% endfor %}
{% endif %}
Thanks
It is difficult to follow, maybe if you have code on github somewhere it would be easier.
It sounds as though you have a db session, and after you pass it into a job, the session is no longer accessible outside the job.
Are you using the extensions pattern (similar to this example) to create you db?
You could have something like
from flask_sqlalchemy import SQLAlchemy
from flask_sqlalchemy_caching import CachingQuery
db = SQLAlchemy(query_class=CachingQuery)
in your extensions.py and then import it where you need db connections, and use it inside the app_context().
In your init.py you would still need to also import db
and initialize it with db.init_app(app)
Is there any chance that when running a job using the scheduler within an app context that it can cause a previous session to detach?
i am using version 1.12.3 of flask-apscheduler, I only get the following error when running a job that uses the database. If I run a job that just prints to screen, I do not get this error.
sqlalchemy.orm.exc.DetachedInstanceError: Parent instance <Users at 0x2792f1448b0> is not bound to a Session; lazy load operation of attribute 'profile' cannot proceed.
The call for profile is used by flask-login on @login_required decorator. I have tried many scenarios and this only seems to happen when a job runs. I am using the @scheduler.task decorator to start the job and have my code within this block
with scheduler.app.app_context():