E
E
egregors2014-05-23 09:15:19
Flask
egregors, 2014-05-23 09:15:19

How to access the current application context from a new thread?

There is a class that accepts an object that needs to be added for deletion to the sqlalchemy session.
If you implement this class within the current thread, no problems arise:

from ..extensions import db
# db = SQLAlchemy()

class Remover(object):
    """docstring for Remover"""
    def __init__(self, obj):
        super(Remover, self).__init__()
        self.obj = obj
        self.remove()

    def remove(self):
        try:
            db.session.delete(self.obj)
            db.session.commit()
        except Exception, e:
            raise e

u = User().query.first()
Remover(u)


But it is necessary to make sure that adding an object to the session and commit does not happen immediately, but after n seconds. To do this, in a new thread, I create a timer, after which the remove () method is executed

from threading import Timer
from ..extensions import db
# db = SQLAlchemy()


class Remover(object):
    """docstring for Remover"""
    def __init__(self, obj):
        super(Remover, self).__init__()
        self.obj = obj
        self.t = Timer(7, self.remove)
        self.t.start()

    def remove(self):
        try:
            db.session.delete(self.obj)
            db.session.commit()
        except Exception, e:
            raise e

    def cancel(self):
        self.t.cancel()

u = User().query.first()
Remover(u)


In this case, an exception is thrown:
RuntimeError: application not registered on db instance and no application bound to current context


Please tell me how to work with contexts from additional threads, so that it would be possible to correctly implement the described class?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Dmitry, 2014-05-23
@dmtrrr

If you need to implement deferred deletion, then this is done differently and without threads.
In your case, you need to pass to Remover not a reference to an object, but a user id.
Then, in the Remover, open a new connection to the database and delete the user with the passed id.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question