What to do to run makemigrations/migrate on heroku when deploying changed models from github? - django

I have deployed app from github repository to the heroku account of my customer as collaborator but this time I had to add some new models.
However I realized that when I deploy my changes from github heroku does not run makemigrations and migrate.
I I read some answers on stackoverflow and understood this is how it is supposed to be.
However my question is what should I do ? What is the best practise to deploy change models to heroku app. (I assume it is not deleting and recreating my app again since customer already has data there.)
(I am able to run makemigrations and migrate from the bash manually but when I have 30+ deployments it's a pain)

Check out the new feature on Heroku called "Release Phase": https://devcenter.heroku.com/articles/release-phase It will allow you to run migrations during the deployment. Just add whatever command you want to your Procfile, like this:
web: your_web_command
release: python manage.py migrate
The release command will run after your app is done building, and before it's launched.

Related

Django REST committing migration files to production

I have a django REST project and a PostgreSQL database deployed to DigitalOcean. When I develop locally, I have a separate dockerized REST server and a separate PostgreSQL database to test backend features without touching production data.
My question arises when I'm adding/modifying model fields that require me to make migrations using python [manage.py](https://manage.py) makemigrations and python [manage.py](https://manage.py) migrate command. Here is my current situation so far:
What I was supposed to do
IN LOCAL ENV, to create the migration files,
python manage.py makemigrations
python manage.py migrate
Now commit these newly created files, something like below.
git add app/migrations/...
git commit -m 'add migration files' app/migrations/...
IN PRODUCTION ENV, run only the below command.
python manage.py migrate
What I did so far
IN LOCAL ENV, created the migration files,
python manage.py makemigrations
python manage.py migrate
I committed & pushed the changes to production WITHOUT the created migration file
IN PRODUCTION ENV, ran BOTH commands.
python manage.py makemigrations
python manage.py migrate
The production server successfully added the isActive field to the database and is working fine, but I still have a 0011_user_isActive.py migration file in my local changes that hasn't been staged/committed/pushed to github repo.
And because I ran makemigrations command in production env, it probably created the same migration file that I haven't pushed from local env.
My questions are:
What happens if I push the local migration file to production? Wouldn't it create a conflict when I run migration command on digitalocean console in the future?
How should I fix this situation?
I am just scared I'm going to corrupt/conflict my production database as I'm very inexperienced in databases and have too much to risk at the moment. Would appreciate any tips on best practices when dealing with such situations!
As docs says:
The migration files for each app live in a “migrations” directory inside of that app, and are designed to be committed to, and distributed as part of, its codebase. You should be making them once on your development machine and then running the same migrations on your colleagues’ machines, your staging machines, and eventually your production machines.
So it's best practice is to push your migration files and make your local and production migration files sync.
And if you got conflict when pushing migraions files and pulling them, the makemigrations --merge command is for solving that.
Also docs says:
Because migrations are stored in version control, you’ll occasionally come across situations where you and another developer have both committed a migration to the same app at the same time, resulting in two migrations with the same number.
Don’t worry - the numbers are just there for developers’ reference, Django just cares that each migration has a different name. Migrations specify which other migrations they depend on - including earlier migrations in the same app - in the file, so it’s possible to detect when there’s two new migrations for the same app that aren’t ordered.
When this happens, Django will prompt you and give you some options. If it thinks it’s safe enough, it will offer to automatically linearize the two migrations for you. If not, you’ll have to go in and modify the migrations yourself - don’t worry, this isn’t difficult, and is explained more in Migration files below.
Also be aware that in case of updating existed data in production, you can use RunPython in migration file. Read about it here.

Will migrations that I make to a django app reflect on the DB that is present in Kubernetes?

I have a Django application and I'm using MariaDB as the database. Both of them have been deployed to a namespace on kubernetes. Now I want to add an additional field, so I made changes in the models.py file in the django app. These changes were made locally - I pulled the code from GIT and just made the changes locally. Normally to apply the changes, I have to run manage.py makemigrations and manage.py migrate and all the changes would've been reflected on to the DB if the DB was present locally.
So now my questions are
How can I apply the changes to MariaDb that is there on Kubernetes ?
Will running manage.py makemigrations and manage.py migrate locally and redeploying the django app to kubernetes solve this issue ?
TLDR;
If you don't require multiple replicas, then the simplest way to do it would be to run your migrations when the container starts.
If you require multiple replicas, then you'll have to get creative with jobs and init containers.There's a good article with more info on it here: https://andrewlock.net/deploying-asp-net-core-applications-to-kubernetes-part-7-running-database-migrations/

Django migrations not persisting

My django app is containerized along side postgresql. The problem is that migrations do not seem to be persisting in the directory. Whenever I run docker exec -it <container_id> python manage.py makemigrations forum, the same migrations are detected. If I spin down the stack and spin it back up the and run makemigrations again, I see the same migrations detected. Changes to the fields, adding models, deleting models, none ever get detected. These migrations that do appear seem to be getting written to the database, as when I try to migrate, I get an error that there are existing fields already. But if I look at my migrations folder, only the init.py folder is present. All the migrate commands add no changes to the migrations folder.
I also tried unregistered the post model from the admin and spinning up the stack, yet I still see it present in the admin. Same things with changes to the templates. No change I make sticks from inside docker seems to stick.
*Note this problem started after I switched to wsl 2 and enabled it in docker desktop (windows)
**Update migrations can be made from bash of docker container
I found out what the problem was. My docker-stack.yml file was pointed to a directory that did not exist in the dockerfile.

Running ./manage.py migrate during Heroku deployment

I am working on a Django app, and I would like my Database migrations to be run when deploying on Heroku.
So far we have simply put the following command in the Procfile:
python manage.py migrate
When deploying the migrations are indeed run, but they seem to be run once for each dyno (and we use several dynos). As a consequence, data migrations (as opposed to pure schema migrations) are run several times, and data is duplicated.
Running heroku run python manage.py migrate after the deployment is not satisfactory since we want the database to be in sync with the code at all times.
What is the correct way to do this in Heroku?
Thanks.
This is my Procfile and it is working exactly as you describe:
release: python manage.py migrate
web: run-program waitress-serve --port=$PORT settings.wsgi:application
See Heroku docs on defining a release process:
https://devcenter.heroku.com/articles/release-phase#defining-a-release-command
The release command is run immediately after a release is created, but before the release is deployed to the app’s dyno formation. That means it will be run after an event that creates a new release:
An app build
A pipeline promotion
A config var change
A rollback
A release via the platform API
The app dynos will not boot on a new release until the release command finishes successfully.
If the release command exits with a non-zero exit status, or if it’s shut down by the dyno manager, the release will be discarded and will not be deployed to the app’s formation.
Be aware, however, this feature is still in beta.
Update:
When you have migrations that remove models and content types, Django requires a confirmation in the console
The following content types are stale and need to be deleted:
...
Any objects related to these content types by a foreign key will also be deleted. Are you sure you want to delete these content types? If you're unsure, answer 'no'. Type 'yes' to continue, or 'no' to cancel:
The migrate command in your Procfile does not respond and the release command fails. In this scenario, remove the migrate line, push live, run the migrate command manually, then add it back for future deploys.
The migrate does automatically runs on Heroku, but for now you can safely do it once your dyno is deployed with heroku run python manage.py migrate.
If production, you can put your app in maintenance first with heroku maintenance:on --app=<app name here>
Setup your Procfile like in the docs
release: python manage.py migrate
web: gunicorn myproject.wsgi --log-file -
documented at https://devcenter.heroku.com/articles/release-phase#specifying-release-phase-tasks
You can create a file bin/post_compile which will run bash commands after the build.
Note that it is still considered experimental.
Read here for more buildpack info.
See here for an example
Alternatively, Heroku is working on a new Releases feature, which aims to simplify and solve this process. (Currently in Beta).
Good luck!

heroku - DatabaseError: relation "south_migrationhistory" does not exist

i purchased an outsource service to develop a web site in django to be deployed in heroku and AWS S3 (boto package).
Unfortunately the developer did not comment the code, despite it was asked, and left the project uncompleted for following up with a bigger client.
I've hired another django 'expert' to fix a part which was not developed, and he want to (over)charge for deployment testing, which i think should be a normal matter for good practices! i am working on my own budject, and need to work it out myself.
I was able to make the project run locally and make myself the frontend templates which were not fully developed, but I am having issues in deploying the code on my own staging environment.
I set up a staging environment under my credential to check if everything is ok, before pushing to production.
I think I almost get there, though:
heroku run python manage.py migrate --all --noinput --app my-app-staging
generate in the console:
Running `python manage.py migrate --all --noinput` attached to terminal... up, run.4833
DatabaseError: relation "south_migrationhistory" does not exist
LINE 1: ...gration", "south_migrationhistory"."applied" FROM "south_mig...
In the browser:
DatabaseError at /
relation "django_site" does not exist
LINE 1: ..."django_site"."domain", "django_site"."name" FROM "django_si...
^
Request Method: GET
Request URL: http://my-app-staging.herokuapp.com/
Django Version: 1.5.6
Exception Type: DatabaseError
Exception Value:
relation "django_site" does not exist
LINE 1: ..."django_site"."domain", "django_site"."name" FROM "django_si...
^
Exception Location: /app/.heroku/python/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py in execute, line 5
I checked my settings and they look ok:
i check AWS S3 bucket and it is able to write there;
settings in heroku console display that the db has been created.
I followed:
Heroku created table but when I'll migrate, he says that doesn't created
but it looks my locals.py are ok too, and in my local git branch .gitignore will exclude db.sqlite
My git and heroku ssh keys have been generated and added, so i dont' think it is an issue of authentification.
How could i check that the db is properly connected to django project and I am not invalidated?
Could you please help in debriefing to understand what this error means and how to solve it?
So much thank you.
It sounds like you might not have created the initial South migration tables on your staging server. This is actually done using syncdb:
Once South is added in, you’ll need to run ./manage.py syncdb to make the South migration-tracking tables (South doesn’t use migrations for its own models, for various reasons).
To run this on Heroku, you'll probably want to use something like
heroku run python manage.py syncdb
Once this is done, you should be able to move forward with the South commands.