datamade / how-to

📚 Doing all sorts of things, the DataMade way
MIT License
80 stars 12 forks source link

How to deploy to Heroku after changes to PostgreSQL extension schema management #285

Closed derekeder closed 1 year ago

derekeder commented 1 year ago

Heroku pushed up a breaking change that impacts our Django / Postgres stack and prevents us from deploying.

The error is related to how Heroku Postgres handles extensions. As PostGIS is an extension to Postgres and we use it as the default database engine in all of our Django apps, this will cause an error when deploying any of our apps, likely in the migration step:

Traceback (most recent call last):

  File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 82, in _execute

    return self.cursor.execute(sql)

psycopg2.errors.UndefinedTable: relation "spatial_ref_sys" does not exist

Until a fix is made on Heroku's end, we have found workarounds to deploy our apps:

  1. If the app does not use PostGIS or GeoDjango features at all, you can change the database engine in settings.py from django.contrib.gis.db.backends.postgis to django.db.backends.postgresql. Example: https://github.com/datamade/arts-census/pull/219/files
  2. If your app does use PostGIS features, you can apply a fix to your database by putting your database into and out of maintenance mode on Heroku. NOTE: This is only allowed on production apps. Steps to do this are: a. install the Heroku data maintenance CLI: https://devcenter.heroku.com/articles/data-maintenance-cli-commands#installation b. set your app to maintenance mode: heroku maintenance:on --app APP_NAME c. schedule maintenance on your database to happen now: heroku data:maintenances:schedule DATABASE --weeks 0 --app APP_NAME d. this will take up to 30 minutes for Heroku to complete. You can check the status on the detail page for your Heroku Postgres addon. If you try to run any further maintenance commands, it will respond with a message like Your replacement database is being prepared. Please try again later. e. when its ready, run maintenance on your app: heroku pg:maintenance:run DATABASE --app APP_NAME --force f. this step should be pretty quick - it will respond with Maintenance triggered g. once complete, turn maintenance mode off: heroku maintenance:off --app APP_NAME

Once either of these workarounds have been made, you should be able to trigger a deploy successfully on your app.

smcalilly commented 1 year ago

if the --weeks 0 gives you an error, or it schedules the maintenance for the future, try setting the --weeks flag to -1 so it's scheduled earlier. also, i didn’t have to run heroku pg:maintenance:run DATABASE --app ccfp-asset-dashboard-prod --force — it appears the maintenance already happened by the time i was at the command line to run that.

smcalilly commented 1 year ago

@derekeder can we close this, since this was only a temporary thing right?

derekeder commented 1 year ago

yes, we're past the need for this. we can close