django - 如何在 Dockerized Django 中运行迁移?

标签 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 构建
    • 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 在非常有用的讨论中让我了解,正在增加,以便迁移显示在我的本地机器上。

所以基本上,我的迁移尝试 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

最佳答案

有很多方法可以实现这一目标。

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

docker 文件

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

关于django - 如何在 Dockerized Django 中运行迁移?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48716358/

相关文章:

python - IntegrityError : (1062, key 条目重复)

Django Rest Framework、HyperlinkedModelSerializers、ModelViewSets 和可写的 GenericForeignKeys : how?

django - 是否可以允许GitHub上的dependabot自动将 "bump"软件升级到新版本?

postgresql - 如何将带有日语文本的 CSV 导入到 PostgreSQL 表中?

java - 当 select 不返回任何行时,MyBatis 的特殊结果

docker - "docker-compose down"如何知道哪些内容应该被删除?

Django 登录不显示错误

performance - PostgreSQL 查询计划是否取决于表行数?

node.js - API设计——分成不同的子域(微服务)

docker - 在 docker 容器上安装多个卷?