【问题标题】:How do I run migrations in Dockerized Django?如何在 Dockerized Django 中运行迁移?
【发布时间】:2018-07-20 20:17:14
【问题描述】:

我关注了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

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

我显然不知道这里发生了什么,所以如果有人能告诉我如何成功地更改模型和运行数据库迁移,我将不胜感激。如果你能帮助我概念化当我运行这些必须让 web 和 postgres 图像一起工作的命令时发生了什么,那么加分。

编辑:什么对我有用

@MazelTov 的建议都将有助于自动化流程,因为我越来越习惯于使用 Docker 进行开发,但我缺少的东西,@MazelTov 在一个非常有用的讨论中让我参与,正在安装以便迁移显示在我的本地机器上。

所以基本上,我的 Migration Attempt 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

【问题讨论】:

    标签: django postgresql docker docker-compose


    【解决方案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"]
    

    入口点.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 服务运行迁移命令

    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
    

    【讨论】:

    • 感谢您的回复!我无法得到你的任何建议......你愿意在聊天室里帮助我吗?无论哪种方式,我都会尝试描述我遇到的情况。首先,提交迁移文件听起来是个好主意,但我不知道如何将我在 docker 容器中生成的迁移文件恢复到我的本地文件中。无论哪种方式,将 makemigrations 或 migrate 放在入口点似乎都没有做任何事情......从单独的容器运行迁移的第二种方法抱怨找不到 manage.py......
    • 第二种方法需要将 dockerfile 中的WORKDIR 设置为您项目所在的文件夹(manage.py 文件),因为如果您不在 dockerfile 中设置 WORKDIR,您很可能会在 root @ 中运行命令987654325@
    • 好的,如果我在新的虚拟机上从头开始构建,我得到了类似于第二种方法的部分工作,但是在我对模型进行任何更改后它仍然失败。我认为主要问题是我不知道如何在创建后进行迁移。我使用命令 bash -c "python manage.py makemigrations todo && python manage.py migrate" 在 docker 容器中执行这两个命令。当我停止这些容器,对模型进行更改,并再次运行 buildup 时,它创建了另一个 0001_initial.py 迁移文件并说“没有要应用的迁移”
    • 那么按照这些思路,您知道我如何使用我的 docker 设置运行makemigrations,从而将迁移文件保留在我的主机目录中,以便每次都将它们复制到 docker 容器中我重建?我只会创建一个本地 conda 环境并在本地安装 postgres,并希望它与 docker 环境足够接近以使一切正常,但这会破坏通过 docker 拥有可重现环境的意义
    • 这是一个很好的例子,为什么你应该在远程机器(例如)Gitlab-CI 上构建图像,因为你会发现所有必要的文件都必须提交给 git.... 来解决你的问题。 .. 当你构建图像时,我相信你复制了图像中的代码,那你为什么不在那里运行makemigrations
    【解决方案2】:

    我通过这样做解决了这个问题:

    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 那里得到的。

    【讨论】:

      猜你喜欢
      • 2018-11-06
      • 2021-06-13
      • 2019-09-18
      • 2021-06-23
      • 2018-05-04
      • 2013-02-15
      • 1970-01-01
      • 2015-07-26
      • 1970-01-01
      相关资源
      最近更新 更多