Heroku postgres postgis - выпуски django завершаются с ошибкой: отношение «spatial_ref_sys» не существует

1 августа 2022 г. компания Heroku изменила управление схемой расширения PostgreSQL. (https://devcenter.heroku.com/changelog-items/2446)

С тех пор каждое развертывание нашего существующего приложения django 4.0 в Heroku терпит неудачу на этапе выпуска, сборка завершается успешно.

Кто-нибудь сталкивался с такой же проблемой? Есть ли обходной путь для отправки новой версии в Heroku, кроме переустановки расширения postgis?

Если я правильно понимаю изменения, Heroku добавил схему под названием «heroku_ext» для вновь созданных расширений. Поскольку расширение уже существует в нашем случае, оно не должно быть затронуто.

All currently installed extensions will continue to work as intended.

Следуя полным журналам выпуска через git push:

git push staging develop:master
Gesamt 0 (Delta 0), Wiederverwendet 0 (Delta 0), Pack wiederverwendet 0
remote: Compressing source files... done.
remote: Building source:
remote: 
remote: -----> Building on the Heroku-20 stack
remote: -----> Using buildpacks:
remote:        1. https://github.com/heroku/heroku-geo-buildpack.git
remote:        2. heroku/python
remote: -----> Geo Packages (GDAL/GEOS/PROJ) app detected
remote: -----> Installing GDAL-2.4.0
remote: -----> Installing GEOS-3.7.2
remote: -----> Installing PROJ-5.2.0
remote: -----> Python app detected
remote: -----> Using Python version specified in runtime.txt
remote: -----> No change in requirements detected, installing from cache
remote: -----> Using cached install of python-3.9.13
remote: -----> Installing pip 22.1.2, setuptools 60.10.0 and wheel 0.37.1
remote: -----> Installing SQLite3
remote: -----> Installing requirements with pip
remote: -----> Skipping Django collectstatic since the env var DISABLE_COLLECTSTATIC is set.
remote: -----> Discovering process types
remote:        Procfile declares types -> release, web, worker
remote: 
remote: -----> Compressing...
remote:        Done: 156.1M
remote: -----> Launching...
remote:  !     Release command declared: this new release will not be available until the command succeeds.
remote:        Released v123
remote:        https://myherokuapp.herokuapp.com/ deployed to Heroku
remote: 
remote: This app is using the Heroku-20 stack, however a newer stack is available.
remote: To upgrade to Heroku-22, see:
remote: https://devcenter.heroku.com/articles/upgrading-to-the-latest-stack
remote: 
remote: Verifying deploy... done.
remote: Running release command...
remote: 
remote: Traceback (most recent call last):
remote:   File "/app/.heroku/python/lib/python3.9/site-packages/django/db/backends/utils.py", line 87, in _execute
remote:     return self.cursor.execute(sql)
remote: psycopg2.errors.UndefinedTable: relation "spatial_ref_sys" does not exist
remote: 
remote: 
remote: The above exception was the direct cause of the following exception:
remote: 
remote: Traceback (most recent call last):
remote:   File "/app/manage.py", line 22, in <module>
remote:     main()
remote:   File "/app/manage.py", line 18, in main
remote:     execute_from_command_line(sys.argv)
remote:   File "/app/.heroku/python/lib/python3.9/site-packages/django/core/management/__init__.py", line 446, in execute_from_command_line
remote:     utility.execute()
remote:   File "/app/.heroku/python/lib/python3.9/site-packages/django/core/management/__init__.py", line 440, in execute
remote:     self.fetch_command(subcommand).run_from_argv(self.argv)
remote:   File "/app/.heroku/python/lib/python3.9/site-packages/django/core/management/base.py", line 414, in run_from_argv
remote:     self.execute(*args, **cmd_options)
remote:   File "/app/.heroku/python/lib/python3.9/site-packages/django/core/management/base.py", line 460, in execute
remote:     output = self.handle(*args, **options)
remote:   File "/app/.heroku/python/lib/python3.9/site-packages/django/core/management/base.py", line 98, in wrapped
remote:     res = handle_func(*args, **kwargs)
remote:   File "/app/.heroku/python/lib/python3.9/site-packages/django/core/management/commands/migrate.py", line 106, in handle
remote:     connection.prepare_database()
remote:   File "/app/.heroku/python/lib/python3.9/site-packages/django/contrib/gis/db/backends/postgis/base.py", line 26, in prepare_database
remote:     cursor.execute("CREATE EXTENSION IF NOT EXISTS postgis")
remote:   File "/app/.heroku/python/lib/python3.9/site-packages/sentry_sdk/integrations/django/__init__.py", line 544, in execute
remote:     return real_execute(self, sql, params)
remote:   File "/app/.heroku/python/lib/python3.9/site-packages/django/db/backends/utils.py", line 67, in execute
remote:     return self._execute_with_wrappers(
remote:   File "/app/.heroku/python/lib/python3.9/site-packages/django/db/backends/utils.py", line 80, in _execute_with_wrappers
remote:     return executor(sql, params, many, context)
remote:   File "/app/.heroku/python/lib/python3.9/site-packages/django/db/backends/utils.py", line 89, in _execute
remote:     return self.cursor.execute(sql, params)
remote:   File "/app/.heroku/python/lib/python3.9/site-packages/django/db/utils.py", line 91, in __exit__
remote:     raise dj_exc_value.with_traceback(traceback) from exc_value
remote:   File "/app/.heroku/python/lib/python3.9/site-packages/django/db/backends/utils.py", line 87, in _execute
remote:     return self.cursor.execute(sql)
remote: django.db.utils.ProgrammingError: relation "spatial_ref_sys" does not exist
remote: 
remote: Sentry is attempting to send 2 pending error messages
remote: Waiting up to 2 seconds
remote: Press Ctrl-C to quit
remote: Waiting for release.... failed.
To https://git.heroku.com/myherokuapp
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
28
0
1 848
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Я отслеживаю очень похожую проблему. Я был в контакте с героку. В моей предыдущей ошибке упоминалось расширение pgaudit, теперь я вижу ту же ошибку, что и вы. Я обновлю здесь, если узнаю о решении.

System check identified no issues (5 silenced).
Traceback (most recent call last):
File "/app/.heroku/python/lib/python3.10/site-packages/django/db/backends/utils.py", line 87, in _execute
return self.cursor.execute(sql)
psycopg2.errors.UndefinedTable: relation "spatial_ref_sys" does not exist
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/app/manage.py", line 40, in
main()
File "/app/manage.py", line 36, in main
execute_from_command_line(sys.argv)
File "/app/.heroku/python/lib/python3.10/site-packages/django/core/management/init.py", line 446, in execute_from_command_line
utility.execute()
File "/app/.heroku/python/lib/python3.10/site-packages/django/core/management/init.py", line 440, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/app/.heroku/python/lib/python3.10/site-packages/django/core/management/base.py", line 414, in run_from_argv
self.execute(*args, **cmd_options)
File "/app/.heroku/python/lib/python3.10/site-packages/django/core/management/base.py", line 460, in execute
output = self.handle(*args, **options)
File "/app/.heroku/python/lib/python3.10/site-packages/django/core/management/base.py", line 98, in wrapped
res = handle_func(*args, **kwargs)
File "/app/.heroku/python/lib/python3.10/site-packages/django/core/management/commands/migrate.py", line 106, in handle
connection.prepare_database()
File "/app/.heroku/python/lib/python3.10/site-packages/psqlextra/backend/base.py", line 32, in prepare_database
super().prepare_database()
File "/app/.heroku/python/lib/python3.10/site-packages/django/contrib/gis/db/backends/postgis/base.py", line 26, in prepare_database
cursor.execute("CREATE EXTENSION IF NOT EXISTS postgis")
File "/app/.heroku/python/lib/python3.10/site-packages/sentry_sdk/integrations/django/init.py", line 544, in execute
return real_execute(self, sql, params)
File "/app/.heroku/python/lib/python3.10/site-packages/django/db/backends/utils.py", line 67, in execute
return self._execute_with_wrappers(
File "/app/.heroku/python/lib/python3.10/site-packages/django/db/backends/utils.py", line 80, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/app/.heroku/python/lib/python3.10/site-packages/django_read_only/init.py", line 74, in blocker
return execute(sql, params, many, context)
File "/app/.heroku/python/lib/python3.10/site-packages/django/db/backends/utils.py", line 84, in _execute
with self.db.wrap_database_errors:
File "/app/.heroku/python/lib/python3.10/site-packages/django/db/utils.py", line 91, in exit
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/app/.heroku/python/lib/python3.10/site-packages/django/db/backends/utils.py", line 87, in _execute
return self.cursor.execute(sql)
django.db.utils.ProgrammingError: relation "spatial_ref_sys" does not exist
Sentry is attempting to send 2 pending error messages
Waiting up to 2 seconds
Press Ctrl-C to quit

ОБНОВЛЕНИЕ: вот последний ответ, который я получил от представителя heroku. Спасибо за ваш ответ. Похоже, что эта новая ошибка является известной проблемой, над которой активно работает наша команда по обработке данных; они ожидают, что исправление будет выпущено уже сегодня. Я буду следить за их прогрессом и сообщу вам, как только исправление будет реализовано.

Rory-R-Reyes 02.08.2022 19:52

Спасибо @Rory-R-Reyes, хорошо, что я не одинок с этим.

Simon 02.08.2022 20:45

Спасибо @Rory-R-Reyes, сегодня мы столкнулись с точно такой же проблемой в наших приложениях.

Chris B. 02.08.2022 21:58

Также нарушается наш процесс восстановления резервной копии.

seigel 03.08.2022 02:22

Сломал много вещей, в том числе нашу функциональную среду. Новые созданные среды также не распознают расширение даже после успешной установки.

John Cartwright 03.08.2022 02:24

Я получил это обновление около 7:30 CST. Я не получал никаких обновлений с тех пор... я хотел вернуться к вам, чтобы подтвердить, что наша команда все еще работает над этой проблемой. Мы нашли причину проблемы и работаем над развертыванием исправления как можно скорее. Пожалуйста, будьте уверены, что на данный момент это наш наивысший приоритет, и мы продолжаем работать над смягчением этого воздействия и поиском решений как можно скорее.

Rory-R-Reyes 03.08.2022 19:34

У нас также была ошибка перед этой, в которой говорилось pgaudit stack is not empty, что требовало от меня ручного перевода наших баз данных в режим обслуживания, чтобы их ротировать. https://devcenter.heroku.com/articles/data-maintenance-cli-commands#heroku-data-maintenances-schedule Эта статья помогла мне обойти первую проблему, но теперь я нахожусь в той же лодке с ошибкой space_ref_sys.

Моя команда тоже столкнулась с этим. Не могли дождаться, пока Heroku исправят, поэтому мы сделали небольшую хирургическую операцию. Не для всех применимо, но так как мы мало используем PostGIS, это не так уж и плохо.

Это был мой контрольный список для каждой затронутой базы данных:

  • резервное копирование базы данных
  • включить режим обслуживания
  • создайте новые примитивные столбцы float во всех таблицах, которые использовали типы geography для хранения необработанных данных широты / долготы
  • записать значения из полей geography в новые столбцы
  • удалить расширение postgis: DROP EXTENSION postgis CASCADE;
  • воссоздать расширение: CREATE EXTENSION IF NOT EXISTS postgis;
  • воссоздайте наши поля geography и заполните их из новых столбцов
  • удалить новые временные столбцы
  • воссоздать соответствующие индексы

Все идет нормально.

Мы также столкнулись с этой проблемой при попытке использовать heroku pg:backups:restore и heroku pg:copy — существующие снимки резервных копий нельзя восстановить, если они содержат установленные расширения.

Вот обходной путь, который я придумал для наших обзорных приложений, использующих резервную копию базы данных, через pg:backups:restore (может потребоваться включить техническое обслуживание, если вы манипулируете производственной базой данных):

  1. Скопируйте локально базу данных приложения для проверки (та, которая была недавно восстановлена ​​с помощью pg:backups:restore, чтобы получить все данные): heroku pg:pull [Database URL] localdb -a [app-name]

  2. Настройте конфигурацию базы данных приложения на использование localdb, затем подключитесь к psql и выполните: ALTER EXTENSION "hstore" SET SCHEMA heroku_ext;. Запустите эту команду для всех ваших существующих расширений.

Чтобы просмотреть все доступные расширения, которые вы вытащили, запустите \dx. Вам не нужно ничего менять plpgsql он встроен в PostgreSQL

Это будет работать, потому что локально у вас есть все привилегии.

  1. отправьте эту версию обратно в приложение для проверки: heroku pg:push mylocaldb [Database URL] -a [app-name] ==> Для этого ваша база данных должна быть пустой. Вы можете попробовать эту операцию на свежем приложении обзора с пустыми данными. таким образом, он может стать вашей новой базой для всех обзорных приложений.

  2. Убедитесь, что все работает как положено (данные правильно восстановлены). Затем вы можете создать новый дамп базы данных с помощью pg:backups:capture и использовать его в качестве новой резервной копии базы данных для всех ваших новых приложений для проверки.

Источник: https://devcenter.heroku.com/articles/managing-heroku-postgres-using-cli

Мне также пришлось сделать это, потому что, например, УДАЛЕНИЕ расширения hstore и его повторное включение не было подходящим вариантом для нашего случая.

Ответ принят как подходящий

Я работал над этим, перезаписывая движок postgis/base.py, я добавил следующее в свое приложение под db/base.py

from django.contrib.gis.db.backends.postgis.base import (
     DatabaseWrapper as PostGISDatabaseWrapper,
)

class DatabaseWrapper(PostGISDatabaseWrapper):
    def prepare_database(self):
        # This is the overwrite - we don't want to call the
        # super() because of a faulty extension creation
     pass

Тогда в моих настройках я просто указал DATABASES["engine"] = "app.db"

Это не поможет с резервными копиями, но, по крайней мере, я могу снова выпустить.

Вы уверены, что это работает для вас? Я пробовал то же самое, после этого развертывание стало возможным, но я не смог получить доступ к каким-либо данным postgis. Каждый раз, когда я получаю доступ к модели в админке с помощью PointField, я получаю: AttributeError: 'DatabaseOperations' object has no attribute 'select' Это может увеличить ваши проблемы, потому что вы не можете выпустить версию без этого обходного пути, потому что он дает сбой на этапе выпуска развертывания.

Simon 03.08.2022 13:51

Если у вас нет миграций, связанных с PointField, то это лучшее решение на данный момент. Просто добавьте вышеуказанное, разверните и запустите миграции, а затем снова измените движок на django.contrib.gis.db.backends.postgis и повторно разверните

elenag 04.08.2022 11:59

@ Саймон, нет, я не сталкивался с какими-либо проблемами при чтении из БД, вы убедились, что в вашей БД действительно установлен Postgis? В нашем случае это всегда предоставляется Heroku, что, я полагаю, объясняет, почему это работает.

marcinowski 04.08.2022 12:04

@marcinowski Да, ошибка была на мне. Было DATABASES['default']['ENGINE']: 'my.settings.patched_postgis' вместо DATABASES['default']['ENGINE'] = 'my.settings.patched_postgis'. (Скопировал задание из диктовки в другом месте). Отличный обходной путь, спасибо!

Simon 04.08.2022 13:50

Мы использовали этот обходной путь, предоставленный @chedli https://stackoverflow.com/a/73219273/840568.

Но в нашем случае postgis выдавал ошибку о том, что не разрешено перемещать схемы при попытке обходного пути ALTER EXTENSION postgis SET SCHEMA heroku_ext, поэтому нам пришлось выполнить этот дополнительный шаг.

UPDATE pg_extension
  SET extrelocatable = true
    WHERE extname = 'postgis';

ALTER EXTENSION "postgis" SET SCHEMA "heroku_ext";

UPDATE pg_extension
  SET extrelocatable = false
    WHERE extname = 'postgis';

Я попробовал это и получил permission denied for table pg_extension

Doug Harris 04.08.2022 19:59

Единственный доступный способ на данный момент описан @chedli - stackoverflow.com/a/73219273/840568

sfate 04.08.2022 20:47

@sfate, не могли бы вы проголосовать, чтобы это было более заметно, спасибо!

chedli 07.08.2022 17:36

@DougHarris, вы не можете запустить эту команду непосредственно в экземпляре базы данных heroku, вам нужно очистить свою схему на сервере, где у вас есть разрешение

MrMaz 08.08.2022 18:53

@chedli я обновил свой ответ, чтобы сослаться на ваш первоначальный обходной путь и уточнить, что мой ответ является дополнительным шагом.

MrMaz 08.08.2022 18:57

Команда Heroku наконец-то решила проблему :)

Пожалуйста, предоставьте более подробную информацию. Они вернулись? Мой запрос в службу поддержки Heroku получил ответ с запутанным обходным путем.

Doug Harris 05.08.2022 15:41

пожалуйста, уточните. они отменили изменение?

Raghu Varma 05.08.2022 18:26

Да, пожалуйста, уточните. Спасибо.

axoplasm 13.08.2022 20:34

Другие вопросы по теме