Search code examples
herokuflasksqliteceleryflickr

Why is my Flask app deploy to Heroku failing on a sqlite3.OperationalError when my app doens't even use a database?


I'm building a basic web application with Flask. Enter a tag and your email, hit Submit, and a Celery worker (configured to use Redis) grabs images from Flickr, downloads them, zips them up, and sends the zipfile as an attachment to the email provided.

I have not configured my application to use any database, I figured I did not need one. When I try to deploy my application to Heroku, however, I get the following from my error logs:

2017-03-03T18:33:49.500689+00:00 app[web.1]: Traceback (most recent call last):
2017-03-03T18:33:49.500691+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/arbiter.py", line 557, in spawn_worker
2017-03-03T18:33:49.500692+00:00 app[web.1]:     worker.init_process()
2017-03-03T18:33:49.500692+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/workers/base.py", line 126, in init_process
2017-03-03T18:33:49.500693+00:00 app[web.1]:     self.load_wsgi()
2017-03-03T18:33:49.500694+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/workers/base.py", line 136, in load_wsgi
2017-03-03T18:33:49.500694+00:00 app[web.1]:     self.wsgi = self.app.wsgi()
2017-03-03T18:33:49.500695+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/app/base.py", line 67, in wsgi
2017-03-03T18:33:49.500696+00:00 app[web.1]:     self.callable = self.load()
2017-03-03T18:33:49.500697+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/app/wsgiapp.py", line 65, in load
2017-03-03T18:33:49.500697+00:00 app[web.1]:     return self.load_wsgiapp()
2017-03-03T18:33:49.500698+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/app/wsgiapp.py", line 52, in load_wsgiapp
2017-03-03T18:33:49.500699+00:00 app[web.1]:     return util.import_app(self.app_uri)
2017-03-03T18:33:49.500699+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/util.py", line 357, in import_app
2017-03-03T18:33:49.500700+00:00 app[web.1]:     __import__(module)
2017-03-03T18:33:49.500700+00:00 app[web.1]:   File "/app/app.py", line 31, in <module>
2017-03-03T18:33:49.500701+00:00 app[web.1]:     flickr = flickrapi.FlickrAPI(flickr_key, flickr_secret, format='parsed-json')
2017-03-03T18:33:49.500702+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/flickrapi/core.py", line 209, in __init__
2017-03-03T18:33:49.500702+00:00 app[web.1]:     self.flickr_oauth = auth.OAuthFlickrInterface(api_key, secret, self.token_cache)
2017-03-03T18:33:49.500703+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/flickrapi/auth.py", line 166, in __init__
2017-03-03T18:33:49.500704+00:00 app[web.1]:     if oauth_token.token:
2017-03-03T18:33:49.500704+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/flickrapi/tokencache.py", line 180, in token
2017-03-03T18:33:49.500705+00:00 app[web.1]:     (self.api_key, self.lookup_key))
2017-03-03T18:33:49.500709+00:00 app[web.1]: sqlite3.OperationalError: no such table: oauth_tokens

Are Flask applications required to have a database configured before they can be deployed to Heroku? That seems ridiculous.

It seems like it might be an issue with the FlickrAPI. The error looks like it's thrown when the FlickrAPI is using my api_key and secret to authenticate me, but it never threw that error when I was testing locally, and I don't understand why API access would require a database to keep track of a tokencache and oauth_tokens anyway.

Do I need to use a different FlickrAPI module? Do I need to use a database in my application? I'm new to Python and Flask, so I'm probably missing something basic.

Any help would be greatly appreciated!

My requirements.txt:

Flask==0.10.1
Flask-Mail==0.9.1
Jinja2==2.7.3
MarkupSafe==0.23
Werkzeug==0.9.6
amqp==1.4.6
anyjson==0.3.3
argparse==1.2.1
billiard==3.3.0.19
blinker==1.3
celery==3.1.17
click==6.7
flickrapi==2.2.1
gunicorn==19.6.0
itsdangerous==0.24
kombu==3.0.30
oauthlib==2.0.1
pytz==2014.10
ratelimit==1.2.0
redis==2.10.3
requests==2.13.0
requests-oauthlib==0.8.0
requests-toolbelt==0.7.1
six==1.10.0
vine==1.1.3

Solution

  • The FlickrAPI package uses SQLite for its OAuthTokenCache (see code here). And it seems that SQLite is not supported by Heroku (filesystem is ephemeral in Heroku): https://devcenter.heroku.com/articles/sqlite3

    So you might want to look at alternatives in PyPi.