Search code examples
pythondatabaseflaskherokuheroku-postgres

How Do I Access My PostgreSQL Database From a Clock Process Heroku Flask?


I have a custom clock process running in Heroku that sends emails to my users every day.

The problem is I need to access the users from my database and I don't have access to my flask app context since it's running in a different process.

I've been googling for the past hour with no luck so here I am. I tried importing current_app from flask but it gave me this:

Job "check_if_users_did_devotions (trigger: cron[minute='*'], next run at: 2020-07-07 12:49:00 CDT)" raised an exception
Traceback (most recent call last):
  File "C:\Users\smith\PycharmProjects\MyProject\venv\lib\site-packages\apscheduler\executors\base.py", line 125, in run_job
    retval = job.func(*job.args, **job.kwargs)
  File "C:\Users\smith\PycharmProjects\MyProject\MyProject\Tasks.py", line 11, in send_email
    print(current_app)
  File "C:\Users\smith\PycharmProjects\MyProject\venv\lib\site-packages\werkzeug\local.py", line 366, in <lambda>
    __str__ = lambda x: str(x._get_current_object())
  File "C:\Users\smith\PycharmProjects\MyProject\venv\lib\site-packages\werkzeug\local.py", line 306, in _get_current_object
    return self.__local()
  File "C:\Users\smith\PycharmProjects\MyProject\venv\lib\site-packages\flask\globals.py", line 52, in _find_app
    raise RuntimeError(_app_ctx_err_msg)
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().  See the
documentation for more information.

Process finished with exit code -1

I think I might need to connect to the database in the clock process separately but I don't know if that would cause issues having two separate connections to the same database. Any help would be greatly appreciated!


Solution

  • All modern client-server databases that I'm aware of have strategies for handling multiple connections. A very common strategy, Multiversion Concurrency Control (MVCC), is used by PostgreSQL and many other databases:

    When an MVCC database needs to update a piece of data, it will not overwrite the original data item with new data, but instead creates a newer version of the data item. Thus there are multiple versions stored. The version that each transaction sees depends on the isolation level implemented. The most common isolation level implemented with MVCC is snapshot isolation. With snapshot isolation, a transaction observes a state of the data as when the transaction started.

    MVCC provides point-in-time consistent views. Read transactions under MVCC typically use a timestamp or transaction ID to determine what state of the DB to read, and read these versions of the data. Read and write transactions are thus isolated from each other without any need for locking. However, despite locks being unnecessary, they are used by some MVCC databases such as Oracle. Writes create a newer version, while concurrent reads access an older version.

    Basically, each connection you make will have a consistent view of the database. Unless you're doing something really weird, you should be fine.