How do I run migrations in Dockerized Django? - django

I followed a Docker + Django tutorial which was great, in that I could successfully build and run the website following the instructions. However, I can't for the life of me figure out how to successfully run a database migration after changing a model.
Here are the steps I've taken:
Clone the associated git repo
Set up a virtual machine called dev
with docker-machine create -d virtualbox dev
and point to it with eval $(docker-machine env dev)
Built and started it up with:
docker-compose build
and docker-compose up -d
Run initial migration (the only time I'm able to run a migration that appears successful):
docker-compose run web python manage.py migrate
Checked that the website works by navigating to the IP address returned by:
docker-machine ip dev
Make a change to a model. I just added this to the Item model in web/docker_django/apps/todo/models.py file.:
name = models.CharField(default='Unnamed', max_length=50, null=False)
Update the image and restart the containers with:
docker-compose down --volumes
then docker-compose build
then docker-compose up --force-recreate -d
Migration attempt number 1:
I used:
docker-compose run web python manage.py makemigrations todo
Then:
docker-compose run web python manage.py migrate
After the makemigrations command, it said:
Migrations for 'todo':
0001_initial.py:
- Create model Item
When I ran the migrate command, it gave the following message:
Operations to perform:
Synchronize unmigrated apps: messages, todo, staticfiles
Apply all migrations: contenttypes, admin, auth, sessions
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Installing custom SQL...
Running migrations:
No migrations to apply.
So that didn't work.
Migration attempt number 2:
This time I tried running migrations from directly inside the running web container. This looked like this:
(macbook)$ docker exec -it dockerizingdjango_web_1 bash
root#38f9381f179b:/usr/src/app# ls
Dockerfile docker_django manage.py requirements.txt static tests
root#38f9381f179b:/usr/src/app# python manage.py makemigrations todo
Migrations for 'todo':
0001_initial.py:
- Create model Item
root#38f9381f179b:/usr/src/app# python manage.py migrate
Operations to perform:
Synchronize unmigrated apps: staticfiles, messages
Apply all migrations: contenttypes, todo, admin, auth, sessions
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Installing custom SQL...
Running migrations:
Rendering model states... DONE
Applying todo.0001_initial...Traceback (most recent call last):
File "/usr/local/lib/python3.5/site-packages/django/db/backends/utils.py", line 62, in execute
return self.cursor.execute(sql)
psycopg2.ProgrammingError: relation "todo_item" already exists
Moreover, I couldn't find any migrations folders in that container.
I clearly have very little idea what's happening under the hood here, so if someone could show me how to successfully change models and run database migrations I would much appreciate it. Bonus points if you can help me conceptualize what's happening where when I run these commands that have to get the web and postgres images to work together.
EDIT: What worked for me
#MazelTov's suggestions will all be helpful for automating the process as I get more used to developing with Docker, but the thing I was missing, that #MazelTov filled me in on in a very helpful discussion, was mounting so that migrations show up in my local machine.
So basically, my Migration Attempt 1 would have worked just fine if instead of, for example:
docker-compose run web python manage.py makemigrations todo
...I used:
docker-compose run --service-ports -v $(pwd)/web:/usr/src/app web python manage.py makemigrations todo

There are many ways how to achieve this.
1) Run ./manage.py migrate before you start your app (uwsgi, runserver,...) in bash script
Dockerfile
FROM debian:latest
...
# entrypoint, must be executable file chmod +x entrypoint.sh
COPY entrypoint.sh /home/docker/entrypoint.sh
# what happens when I start the container
CMD ["/home/docker/entrypoint.sh"]
entrypoint.sh
#!/bin/bash
./manage.py collectstatic --noinput
# i commit my migration files to git so i dont need to run it on server
# ./manage.py makemigrations app_name
./manage.py migrate
# here it start nginx and the uwsgi
supervisord -c /etc/supervisor/supervisord.conf -n
2) If you have a lot of migration files and you dont want any downtime, you could run the migrate command from seperate docker-compose service
docker-compose.yml
version: '3.3'
services:
# starts the supervisor (uwsgi + nginx)
web:
build: .
ports: ["80:80"]
# this service will use same image, and once the migration is done it will be stopped
web_migrations:
build: .
command: ./manage.py migrate

I solved this by doing:
docker-compose exec web /usr/local/bin/python manage.py makemigrations todo
and then :
docker-compose exec web /usr/local/bin/python manage.py migrate
I got it from this issue.

Related

populating django database using migrations

I created an api that allows to read some data with filters based on the models I created.
and launch the database is empty so I created a script to populate the database.
I then dockerized the app and deployed to AWS.
the issue here is that everytime the container restarts the script is re-run.
I would like to use migrations to do this.
how?
for now the docker entrypoint is
python manage.py wait_for_db
python manage.py makemigrations API
python manage.py migrate
# python import_csv.py
uwsgi --socket :9000 --workers 4 --master --enable-threads --module myapi.wsgi

Heroku doesn't migrate models in Django

I have a Django app deployed on Heroku.
I am trying to switch the database from mySQL to Postgres using the Heroku Postgres addon
I erased all migrations and ran manage.py makemigrations to get a clean migration log.
Then I commit and push.
If I run manage.py migrate on my local machine, this is what I get:
Migrations for 'manager':
manager/migrations/0001_initial.py
- Create model AbiMapping
- Create model MissingContracts
- Create model TempEmailAccounts
- Create model UnsupportedMetaContracts
- Create model Users
- Create model Passwords
- Create model ContractMapping
- Create model Tokens
I added this command to Procfile so migrate runs when I push to Heroku:
release: python3 manage.py migrate
When pushing to Heroku, the migrate call works but it doesn't migrate the models I have in the app:
remote: Verifying deploy... done.
remote: Running release command...
remote:
remote: Operations to perform:
remote: Apply all migrations: admin, auth, contenttypes, manager, sessions
remote: Running migrations:
remote: No migrations to apply.
This is how I setup the database is settings.py:
.env sets environment variables on local machine. On heroku database environment variables are loaded from environment as there is not .env
dotenv_file = os.path.join(BASE_DIR, ".env")
if os.path.isfile(dotenv_file):
dotenv.load_dotenv(dotenv_file)
Setup database:
DATABASES = {}
DATABASES['default'] = dj_database_url.config(conn_max_age=600)
django_on_heroku.settings(locals())
it seems like the database does exist in heroku:
$ heroku config
=== frame-zero Config Vars
DATABASE_URL: postgres://<details of my database address and credentials>
Thank you
Already solved here. the trick is to run the bash on Heroku Dyno first. first run Heroku run bash then inside the bash window run Python manage.py makemigrations and after that Python manage.py migrate.

Django on Heroku - ProgrammingError at / relation "..." does not exist

I'm getting this error. I know you usually get this error because the databases wasn't properly migrated.
When I run heroku local web, the website works fine when I go to localhost:5000.
However after I deploy the app to heroku with git push heroku master, the error comes up.
In other words, it works in my local environment. But it does not work after deploying to heroku.
I have Heroku-Postgres installed as an add-on in heroku.
What could be causing this?
excute migrations and makemigrations in bash heroku. open the terminal in the local project folder and give the following commands:
heroku run bash
~$ ./manage.py makemigrations
~$ ./manage.py migrate
~$ exit
The following steps did it for me
Make all the necessary migrations (python manage.py makemigrations) and migrate (python manage.py migrate) locally,
push to heroku master
and finally running heroku run python manage.py migrate
Solved the issue
I experienced the same error after making a change to a model and then deploying this change to heroku.
The only way I managed to fix this problem was to do the following:
Reset the database in heroku
Delete the migrations files from the migrations folder for the broken app locally (but keep the directory and the __init__.py file)
Run python manage.py makemigrations and python manage.py migrate. This will repopulate the migrations folder with clean migration files.
Push changes to master (ensure that you do not have migrations directories in .gitignore files.
Deploy changes to heroku
Run the heroku shell heroku run bash
Run python manage.py migrate
I was able to do this because my tables did not have much data in, but I would try to avoid resetting the database if I had more data in my tables.

django-background-tasks migrations on heroku

I am trying to migrate dajngo-background-tasks on my app hosted in heroku. Migrations worked normally locally but when I tried to run:
heroku run python manage.py migrate
It returned 'No migrations to apply'
I've added 'background_task', to INSTALLED_APPS
I ran
heroku run python manage.py makemigrations background_task
And it created the required migrations
I even tried running
heroku run python manage.py migrate background_task
causing "CommandError: App 'background_task' does not have migrations."
PS: One thing I noticed is that when running migrate locally I get this text
Apply all migrations: admin, background_task, auth, contenttypes, sessions, <my_app>
But when I run it on the server I get
Apply all migrations: admin, auth, contenttypes, sessions, <my_app>
Every form of help will be very much appreciated!
You must not run makemigrations via heroku run. You must run it locally, commit the resulting migrations and push them to heroku, then run them there.
This is due to missing migrations in the django-background-tasks package. This issue has been fixed in the latest version. If you install 1.1.9 the deployment to heroku should work.

"Unknown command syncdb" running "python manage.py syncdb"

I want to create the tables of one database called "database1.sqlite", so I run the command:
python manage.py syncdb
but when I execute the command I receive the following error:
Unknown command: 'syncdb'
Type 'manage.py help' for usage.
But when I run
manage.py help
I don`t see any command suspicious to substitute
python manage.py syncdb
Version of Python I use: 3.4.2 Version of Django I use:1.9
I would be very grateful if somebody could help me to solve this issue.
Regards and thanks in advance
If you look at the release notes for django 1.9, syncdb command is removed.
Please use migrate instead. Moving forward, the migration commands would be as documented here
Please note that the django-1.9 release is not stable as of today.
Edit: Django 1.9 is stable now
the new django 1.9 has removed "syncdb",
run "python manage.py migrate",
if you are trying to create a super user, run "python manage.py createsuperuser"
$python manage.py syncdb is deprecated and not supported now.
So instead of this follow below instructions..
Whatever model you have created:
First run:
$python manage.py makemigrations
After running this command you model will be reflected in a migration.
Then you have to run:
$python manage.py migrate
Then run server:
$python manage.py runserver
Now, your project will run perfectly.
In Django 1.9 onwards syncdb command is removed. So instead of use that one, you can use migrate command,eg: python manage.py migrate.Then you can run your server by python manage.py runserver command.
Django has removed python manage.py syncdb command now you can simply use python manage.py makemigrations followed bypython manage.py migrate. The database will sync automatically.
You can run the command from the project folder as: "python.exe manage.py migrate", from a commandline or in a batch-file.
You could also downgrade Django to an older version (before 1.9) if you really need syncdb.
For people trying to run Syncdb from Visual Studio 2015:
The option syncdb was removed from Django 1.9 (deprecated from 1.7), but this option is currently not updated in the context menu of VS2015.
Also, in case you didn't get asked to create a superuser you should manually run this command to create one: python.exe manage.py createsuperuser
Run the command python manage.py makemigratons,and than python manage.py migrate to sync.
Alternarte Way:
Uninstall Django Module from environment
Edit Requirements.txt a type Django<1.9
Run Install from Requirments option in the enviroment
Try Syncdb again
This worked for me.
I also tried this command. Lastly I found the release note from django
Features removed in 1.9
The syncdb command is removed.
Djnago Releases note 1.9
I had the same problem, the only thing worked for me was this command.
python3 manage.py migrate --run-syncdb
Running this got me this result.
Ranvijays-Mac:djangodemo rana.singh$ python3 manage.py migrate --run-syncdb
Operations to perform:
Synchronize unmigrated apps: messages, staticfiles
Apply all migrations: admin, auth, contenttypes, msg, sessions
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Running migrations:
Applying msg.0001_initial... OK