如何在Dockerized Django中运行迁移?

时间:2018-02-10 01:30:36

标签: django postgresql docker docker-compose

我跟着一个很棒的Docker + Django tutorial,因为我可以按照说明成功构建并运行网站。但是,我不能为我的生活找出如何在更改模型后成功运行数据库迁移。

以下是我采取的步骤:

  1. 克隆关联的git repo
  2. 设置名为dev

    的虚拟机
    • docker-machine create -d virtualbox dev
    • 并使用eval $(docker-machine env dev)
    • 指向它
  3. 建立并启动它:

    • docker-compose build
    • docker-compose up -d
  4. 运行初始迁移(我唯一能够运行看似成功的迁移)

    • docker-compose run web python manage.py migrate
  5. 通过导航到以下地址返回的IP地址检查网站是否有效:

    • docker-machine ip dev
  6. 对模型进行更改。我刚刚将此添加到 web / docker_django / apps / todo / models.py 文件中的Item模型中。:

    • name = models.CharField(default='Unnamed', max_length=50, null=False)
  7. 更新图像并使用以下命令重新启动容器:

    • docker-compose down --volumes
    • 然后docker-compose build
    • 然后docker-compose up --force-recreate -d
  8. 迁移尝试编号1:

    我用过:

    docker-compose run web python manage.py makemigrations todo
    

    然后:

    docker-compose run web python manage.py migrate
    

    makemigrations命令之后,它说:

    Migrations for 'todo':
      0001_initial.py:
        - Create model Item
    

    当我运行migrate命令时,它给出了以下消息:

    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. 
    

    所以没有用。

    迁移尝试次数2:

    这次我尝试直接在正在运行的Web容器内运行迁移。这看起来像这样:

    (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个文件夹。

    我很清楚这里发生了什么,所以如果有人能告诉我如何成功更改模型和运行数据库迁移,我将非常感激。如果你可以帮助我概念化我在运行这些必须让网络和postgres图像一起工作的命令时发生的事情,那么你将获得奖励积分。

    编辑:什么对我有用

    @ MazelTov的建议对于自动化过程都很有帮助,因为我越来越习惯使用Docker进行开发,但我失踪的是@MazelTov在一个非常有用的讨论中填补了我,正在安装以便迁移显示在我的本地计算机上。

    所以基本上,我的迁移尝试1 如果不是,那就可以正常工作了,例如:

    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
    

2 个答案:

答案 0 :(得分:1)

有很多方法可以达到这个目的。

1)在bash脚本中启动应用程序(uwsgi,runserver,...)之前运行./manage.py migrate

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)如果你有很多迁移文件并且你不想要任何停机时间,你可以从单独的docker-compose服务运行migrate命令

搬运工-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

答案 1 :(得分:1)

我通过以下方法解决了这个问题:

docker-compose exec web /usr/local/bin/python manage.py makemigrations todo

然后:

docker-compose exec web /usr/local/bin/python manage.py migrate 

我是从this issue那里得到的。