Что такое пуленепробиваемый способ восстановления базы данных django с локального компьютера на сервер? - PullRequest
0 голосов
/ 29 апреля 2019

Я не нашел большого количества рекомендаций по этому вопросу - и когда я действительно нашел руководство, не так много, чтобы объяснить некоторые из проблем, которые у меня возникают. Я самообучаюсь Python и Django, которые идут хорошо, но развертывание на сервере - это ... ад. Было бы здорово, если бы был кто-то с пуленепробиваемым рабочим процессом для резервного копирования базы данных Django и ее восстановления на сервере. Со ссылкой на виртуальные среды, миграции, --fake и -initial.

Ради себя - и для любого, кто читает - я собираюсь пройтись по тому, что я сделал, и посмотреть, смогу ли я увидеть, где ошибки - потому что я на этапе кирпичной стены.

Проблема

«Это работает на моей машине» в значительной степени подводит итог, где я нахожусь. Работает нормально. НА МОЕЙ МАШИНЕ.

Мне удалось добраться до точки, где база данных (Postgresql) была восстановлена ​​на моем сервере - Python Anywhere. И мой серверный экземпляр Django общается с базой данных, и некоторые данные обслуживаются. Тем не менее, существуют некоторые проблемы с миграцией, которые сохраняются и в конечном итоге приводят к нескольким фатальным ошибкам в отношении некоторых несуществующих таблиц, например:

Column podcast_show.type does not exist
LINE 1: SELECT "podcast_show"."id", "podcast_show"."type", "podcast_...

Запуск makemigrations / migrate приводит к таким ошибкам, как эта

django.db.utils.IntegrityError: null value in column "id" violates not-null constraint
DETAIL:  Failing row contains (null, curate, 0005_item_tags, 2019-04-29 12:38:32.000168+00).

Окружающая среда

Я нахожусь на Windows, развиваясь локально на Atom У меня есть виртуальная среда с установленным Django 2.1. Я использую GIT для контроля версий (что я только понимаю), и у меня есть несколько pypy установленных приложений django (в virtualENV), которые, думая об этом сейчас, я сделал прямые изменения.

Это был первый «ага» момент, когда я думал, что взломал его. Изменения, которые я внес в пакеты pypy в myLocalVirtualEnv (включая модели), НЕ были включены в мое GIT-репозиторий, которое было отправлено на сервер. Поэтому, когда я установил pip на сервере все зависимости из require.txt, я получил новые версии этих приложений, а не их модифицированные версии.

* Вопрос 1) Каков правильный рабочий процесс, чтобы избежать этого? * Как только я начну изменять пакет pypy, который является зависимостью, я должен переместить его из virtualenv в мою стандартную структуру папок django и работать над ним, как будто это мое собственное приложение?

Резервная копия

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

Готово. Теперь у меня есть большая база данных (3GB несжатого - это огромный?) Файл базы данных appBU. Теперь я использую SFTP (filezilla) для отправки этого файла на мой сервер, поместив его в тот же каталог, что и мой верхний уровень приложений. главная / пользователь / App / приложение

Теперь в консоли postgresql я создаю новую базу данных.

CREATE DATABASE app;

Тогда я создаю пользователя для базы данных. Я не всегда делаю это, если я удалил базу данных и попытался сделать резервную копию снова, я просто использую уже существующих пользователей. В этом случае я запускаю команду DROP DATABASE app; затем приложение CREATE DATABASE; так что я готов с новой базой данных для восстановления. В любом случае, пользователи:

CREATE USER username WITH PASSWORD 'password';

ALTER ROLE username WITH PASSWORD client_encoding TO 'utf8';
ALTER ROLE username SET default_transaction_isolation TO 'read committed';
ALTER ROLE username SET timezone TO 'UTC';

GRANT ALL PRIVILEGES ON DATABASE app TO username;

Теперь я восстанавливаю базу данных во вновь созданную пустую базу данных, которую я только что создал - это изнутри консоли bash (не консоли psql - это заняло некоторое время для тренировки!)

pg_restore -h the-host-address-for-my-postgresql-database -p 11111 -U super -W  -C app < appBU

Вот тут и начинаются проблемы, потому что pg_restore постоянно несчастен, когда улетает, вот такие ошибки я получаю:


pg_restore: [archiver (db)] Error from TOC entry 3347; 0 0 SEQUENCE SET django_comment_flags_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR:  relation "public.django_comment_flags_id_seq" does not exist
LINE 1: SELECT pg_catalog.setval('public.django_comment_flags_id_seq...
                                 ^
    Command was: SELECT pg_catalog.setval('public.django_comment_flags_id_seq', 1, false);
pg_restore: [archiver (db)] Error from TOC entry 3348; 0 0 SEQUENCE SET django_comments_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR:  relation "public.django_comments_id_seq" does not exist
LINE 1: SELECT pg_catalog.setval('public.django_comments_id_seq', 17...
                                 ^
    Command was: SELECT pg_catalog.setval('public.django_comments_id_seq', 17, true);
pg_restore: [archiver (db)] Error from TOC entry 3349; 0 0 SEQUENCE SET django_content_type_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR:  relation "public.django_content_type_id_seq" does not exist
LINE 1: SELECT pg_catalog.setval('public.django_content_type_id_seq'...
                                 ^
    Command was: SELECT pg_catalog.setval('public.django_content_type_id_seq', 22, true);
pg_restore: [archiver (db)] Error from TOC entry 3350; 0 0 SEQUENCE SET django_migrations_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR:  relation "public.django_migrations_id_seq" does not exist
LINE 1: SELECT pg_catalog.setval('public.django_migrations_id_seq', ...
                                 ^
    Command was: SELECT pg_catalog.setval('public.django_migrations_id_seq', 108, true);
pg_restore: [archiver (db)] Error from TOC entry 3351; 0 0 SEQUENCE SET django_site_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR:  relation "public.django_site_id_seq" does not exist
LINE 1: SELECT pg_catalog.setval('public.django_site_id_seq', 1, tru...
                                 ^
pg_restore: [archiver (db)] Error from TOC entry 3352; 0 0 SEQUENCE SET podcast_category_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR:  relation "public.podcast_category_id_seq" does not exist
LINE 1: SELECT pg_catalog.setval('public.podcast_category_id_seq', 1...
                                 ^
    Command was: SELECT pg_catalog.setval('public.podcast_category_id_seq', 1098, true);



pg_restore: [archiver (db)] Error from TOC entry 3353; 0 0 SEQUENCE SET podcast_enclosure_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR:  relation "public.podcast_enclosure_id_seq" does not exist
LINE 1: SELECT pg_catalog.setval('public.podcast_enclosure_id_seq', ...
                                 ^
    Command was: SELECT pg_catalog.setval('public.podcast_enclosure_id_seq', 1, false);



pg_restore: [archiver (db)] Error from TOC entry 3354; 0 0 SEQUENCE SET podcast_episode_guests_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR:  relation "public.podcast_episode_guests_id_seq" does not exist
LINE 1: SELECT pg_catalog.setval('public.podcast_episode_guests_id_s...
                                 ^
    Command was: SELECT pg_catalog.setval('public.podcast_episode_guests_id_seq', 1, false);



pg_restore: [archiver (db)] Error from TOC entry 3355; 0 0 SEQUENCE SET podcast_episode_hosts_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR:  relation "public.podcast_episode_hosts_id_seq" does not exist
LINE 1: SELECT pg_catalog.setval('public.podcast_episode_hosts_id_se...
                                 ^
    Command was: SELECT pg_catalog.setval('public.podcast_episode_hosts_id_seq', 1, false);



pg_restore: [archiver (db)] Error from TOC entry 3356; 0 0 SEQUENCE SET podcast_episode_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR:  relation "public.podcast_episode_id_seq" does not exist
LINE 1: SELECT pg_catalog.setval('public.podcast_episode_id_seq', 19...
                                 ^
    Command was: SELECT pg_catalog.setval('public.podcast_episode_id_seq', 1995295, true);


pg_restore: [archiver (db)] Error from TOC entry 3357; 0 0 SEQUENCE SET podcast_show_categories_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR:  relation "public.podcast_show_categories_id_seq" does not exist
LINE 1: SELECT pg_catalog.setval('public.podcast_show_categories_id_...
                                 ^
    Command was: SELECT pg_catalog.setval('public.podcast_show_categories_id_seq', 3873, true);
pg_restore: [archiver (db)] Error from TOC entry 3358; 0 0 SEQUENCE SET podcast_show_hosts_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR:  relation "public.podcast_show_hosts_id_seq" does not exist
LINE 1: SELECT pg_catalog.setval('public.podcast_show_hosts_id_seq',...
                                 ^
    Command was: SELECT pg_catalog.setval('public.podcast_show_hosts_id_seq', 1, false);
pg_restore: [archiver (db)] Error from TOC entry 3359; 0 0 SEQUENCE SET podcast_show_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR:  relation "public.podcast_show_id_seq" does not exist
LINE 1: SELECT pg_catalog.setval('public.podcast_show_id_seq', 27121...
                                 ^
    Command was: SELECT pg_catalog.setval('public.podcast_show_id_seq', 27121, true);
pg_restore: [archiver (db)] Error from TOC entry 3360; 0 0 SEQUENCE SET podcast_show_itunes_categories_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR:  relation "public.podcast_show_itunes_categories_id_seq" does not exist
LINE 1: SELECT pg_catalog.setval('public.podcast_show_itunes_categor...
                                 ^
    Command was: SELECT pg_catalog.setval('public.podcast_show_itunes_categories_id_seq', 1, false);
pg_restore: [archiver (db)] Error from TOC entry 3361; 0 0 SEQUENCE SET podcast_speaker_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR:  relation "public.podcast_speaker_id_seq" does not exist
LINE 1: SELECT pg_catalog.setval('public.podcast_speaker_id_seq', 1,...
                                 ^
    Command was: SELECT pg_catalog.setval('public.podcast_speaker_id_seq', 1, false);
pg_restore: [archiver (db)] Error from TOC entry 3362; 0 0 SEQUENCE SET taggit_tag_id_seq postgres
pg_restore: [archiver (db)] could not execute query: ERROR:  relation "public.taggit_tag_id_seq" does not exist
LINE 1: SELECT pg_catalog.setval('public.taggit_tag_id_seq', 49920, ...
                                 ^
    Command was: SELECT pg_catalog.setval('public.taggit_tag_id_seq', 49920, true);


pg_restore: [archiver (db)] Error from TOC entry 2912; 2604 34102 DEFAULT taggit_taggeditem id postgres
pg_restore: [archiver (db)] could not execute query: ERROR:  relation "public.taggit_taggeditem_id_seq" does not exist
    Command was: ALTER TABLE ONLY public.taggit_taggeditem ALTER COLUMN id SET DEFAULT nextval('public.taggit_taggeditem_id_seq'::regclass);

Однако - если я сейчас перейду к своему домену, я смогу увидеть, что данные находятся там, и к ним обращается / обслуживает Django. Сохраняющиеся ошибки убивают определенные страницы, которые запрашивают некоторые данные, упомянутые выше. Если я пытаюсь сделать makemigrations / migrate, я получу это:

django.db.utils.IntegrityError: null value in column "id" violates not-null constraint
DETAIL:  Failing row contains (null, curate, 0006_auto_20190429_1108, 2019-04-29 15:50:36.927028+00).

Для справки, приложение «подкаст», на которое он ссылается, - это модифицированное приложение из моего virtualenv.Однако в этом случае я переместил его из virtualenv и переместил в репозиторий git внутри моего проекта - перенеся весь код с ним.

Кто-нибудь знает, что происходит?

IСледует добавить, что кодовая база обновляется до pythonanywhere через git.Я ставлю изменения на Atom, затем фиксирую их.Затем отправьте их в github, затем перетащите их на сервер с помощью команды bash.

Ответы [ 2 ]

0 голосов
/ 30 апреля 2019

Спасибо за помощь всем. Я тщательно проработал свой проект, выполнил полный «сброс» миграций, поэтому на моем локальном компьютере проблем не было.

В итоге я обнаружил, что PythonAnywhere работает под управлением PSQL 9.4, и я использую PSQL 11.2. Я скачал PSQL 9.4 и попытался выполнить локальное резервное копирование, и каждый раз получаю 150 ошибок. PythonAnywhere не планирует обновлять свою версию PSQL на некоторое время, и данные, которые я создал во время разработки, довольно ценны, поэтому я бы хотел сохранить их.

Таким образом, у меня есть два варианта. Либо я могу предпринять попытку перехода на MYSQL с помощью MYSQL Workbench, надеюсь, сохраняя свои данные в такте, либо я могу полностью отбросить полученные данные, придерживаться PSQL 9.4 и начать заново.

0 голосов
/ 29 апреля 2019

Существует большая разница между pypy (компилятором python) и PyPI (индексом пакета python). Я предполагаю, что вы имеете в виду последнее. Для сторонних пакетов, которые вам нужно изменить, вы должны их разветвить, внести изменения и перенести их на свою вилку; и, наконец, поместите ссылку на ваш форк в вашем файле require.txt. Это головная боль при обслуживании, поэтому, если вы можете получить тот же эффект, используя подклассы и т. Д., Это, как правило, лучшая стратегия.

В итоге, если вы не используете тот же код, все остальное, безусловно, не будет стабильным.

3ГБ (без сжатия) не очень большой для базы данных. Размеры файлов более 4 ГБ могут быть проблематичными в некоторых файловых системах, поэтому сжатие / разбиение резервной копии может быть в будущем.

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

Похоже, что у вас могут быть ошибки данных / ограничений ("нулевое значение ... нарушает ненулевое ограничение"). Вы должны исправить эти ошибки в своей базе данных перед резервным копированием.

Похоже, у вас есть некоторые проблемы с последовательностями автоинкремента postgresql, хотя я понятия не имею, как это исправить в postgresql.

Я бы серьезно предложил взглянуть на pg_dump / pg_restore, а не на какое-нибудь графическое решение, которое выполняет только половину работы, ср. https://www.postgresql.org/docs/9.1/backup-dump.html и Восстановить файл резервной копии postgres с помощью командной строки? .

Если вам нужно полное решение для графического интерфейса, есть Navicat (https://www.navicat.com/en/products/navicat-premium - я довольный пользователь), который, по крайней мере, для баз данных, которые я использую, делает это операцией выбора, копирования и вставки. JetBrains 'DataGrip тоже выглядит способным (https://www.jetbrains.com/datagrip/),, хотя я только играл с ним.

ps: на вашем локальном компьютере вы должны выполнить миграцию и выполнить миграцию перед резервным копированием. Когда вы повторяете эти операции на сервере prod, делать нечего (поскольку вы «скопировали» состояние базы данных в текущей версии).

...