如何在 Dockerized Django 中运行迁移? [英] How do I run migrations in Dockerized Django?
问题描述
我遵循了 Docker + 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.
以下是我采取的步骤:
- 克隆关联的 git repo
设置一个名为
dev
- with
docker-machine create -d virtualbox dev
- 并用
eval $(docker-machine env dev)
指向它
构建并启动它:
docker-compose build
- 和
docker-compose up -d
运行初始迁移(这是我唯一一次能够运行看起来成功的迁移):
docker-compose run web python manage.py migrate
通过导航到返回的 IP 地址来检查网站是否正常工作:
Checked that the website works by navigating to the IP address returned by:
docker-machine ip dev
对模型进行更改.我刚刚将它添加到 web/docker_django/apps/todo/models.py 文件中的 Item
模型中.:
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)
更新镜像并重启容器:
docker-compose down --volumes
- 然后
docker-compose build
- 然后
docker-compose up --force-recreate -d
第 1 次迁移尝试:
我用过:
docker-compose run web python manage.py makemigrations todo
那么:
docker-compose run web python manage.py migrate
在 makemigrations
命令之后,它说:
After the makemigrations
command, it said:
Migrations for 'todo':
0001_initial.py:
- Create model Item
当我运行 migrate
命令时,它给出了以下消息:
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.
所以那没有用.
这次我尝试直接从正在运行的 Web 容器内部运行迁移.这看起来像这样:
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
此外,我在该容器中找不到任何 migrations
文件夹.
Moreover, I couldn't find any migrations
folders in that container.
我显然不知道这里发生了什么,所以如果有人能告诉我如何成功更改模型和运行数据库迁移,我将不胜感激.如果你能帮助我概念化当我运行这些必须让 web 和 postgres 图像协同工作的命令时发生了什么,那就加分.
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.
@MazelTov 的建议都有助于自动化流程,因为我越来越习惯于使用 Docker 进行开发,但是我缺少的东西,@MazelTov 在一个非常有用的讨论中让我补充,正在安装,以便迁移显示在我的本地机器上.
@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.
所以基本上,我的迁移尝试 1 如果不是,例如:
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
...我用过:
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) 在 bash 脚本中启动应用程序(uwsgi、runserver...)之前运行 ./manage.py migrate
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"]
入口点.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) 如果您有很多迁移文件并且不想停机,您可以从单独的 docker-compose 服务运行 migrate 命令
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
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
这篇关于如何在 Dockerized Django 中运行迁移?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!