Django AWS Elastic Beanstalk 迁移数据库

Posted

技术标签:

【中文标题】Django AWS Elastic Beanstalk 迁移数据库【英文标题】:Django AWS Elastic Beanstalk migrate database 【发布时间】:2015-06-14 21:57:56 【问题描述】:

我正在使用 Elastic Beanstalk 将 Django 项目部署到 AWS,并且一直在迁移数据库。

我在哪里:我能够成功部署我的 django 项目并通过 mysubdomain.elasticbeanstalk.com 加载页面。页面加载没有错误,直到我到达需要进行数据库调用的页面。然后我收到类似relation "accounts_user" does not exist LINE 1: SELECT COUNT(*) FROM "accounts_user" 的错误,因为我的数据库尚未迁移。

我尝试过的:我尝试了很多不同的方法。幸运的是,有大量的 *** 帖子和一些教程。不幸的是,他们似乎都在使用不同的版本,他们的建议不适用于我的项目。

我很清楚,我需要在 .ebextensions/ 文件夹内的 foobar.config 文件中运行迁移。这是我想做的基础:

container_commands:
  01_migrate:
    command: "python manage.py migrate --noinput"
    leader_only: true

在日志中,我看到部署后脚本尝试运行但失败了。我没有收到有关该错误的任何其他信息,我看到的唯一内容是“错误:01_migrate 部署后脚本失败”

我发现我需要为命令激活虚拟环境,这是有道理的。从 asdf 我试试这个:

container_commands:
  01_migrate:
    command: "source /opt/python/run/venv/bin/activate && python rlg/manage.py migrate --noinput"
    leader_only: true

但它不起作用。事实上,通过 SSH 我发现我什至没有 /opt/python/ 文件夹,只有 /opt/aws/ 和 /opt/elasticbeanstalk/。所有教程和 SO 问题都参考了这个文件夹,但我没有?

版本: Python 3.4.1、Django 1.7.7、AWS CLI 3.2.1、Postgres 9.3

【问题讨论】:

我被困在同一个地方。我发现:container_commands 不在 docker 容器中执行。它们在 ec2 实例本身上执行。我想我们必须使用类似“docker exec [container_name] /var/app/bin/python manage.py migrate --noinput 之类的东西来执行迁移,不幸的是我仍在努力寻找正确的 [container_name] @SebastianAnnies 太棒了,很高兴我在同一个地方找到了人!感谢您的提示,我也会努力解决这个问题,并让您知道我发现的任何内容 不确定本教程的编写时间,但他们有一个 django 迁移特定部分 docs.aws.amazon.com/elasticbeanstalk/latest/dg/… 【参考方案1】:

更新有关最新 Elastic Beanstalk 版本的信息。

我正在使用64bit Amazon Linux 2016.09 v2.3.3 running Python 3.4

以下命令适用于我,无需激活 virtualenv 或创建应用后部署挂钩。

container_commands:
  01_migrate_db:
    command: "python manage.py db upgrade" <-- insert your migration command here
    leader_only: true

为了证明container commands 将在部署后阶段执行,我对模型进行了更改,生成了更新的迁移脚本,部署了新版本并检查了数据库是否成功迁移:成功!

【讨论】:

那是因为您不是在 Docker 容器中运行 django 应用程序,而是在 python 3.4 映像上运行。在使用 Docker 的设置中,它是不同的(请参阅 cmets 关于在最新的 docker 容器中运行命令)。这是 docker 环境特有的问题。【参考方案2】:

我知道这是一篇旧帖子,但我想在这里发布我的答案,因为我花了很长时间才弄清楚。

Sebastian 为我指明了正确的方向,但这种方法的问题在于它在部署之前运行(因此您迁移旧代码)

您也可以在 ebextensions 中使用 files 命令并将文件写入 /opt/elasticbeanstalk/hooks/appdeploy/post 但这将在任何实例上运行

你可以把这两件事结合成:

container_commands:
  01migrate:
    command: "mkdir -p /opt/elasticbeanstalk/hooks/appdeploy/post/ && echo -e '#!/bin/bash\ndocker exec `docker ps -a -q | head -n 1` python <path_to_code> migrate' > /opt/elasticbeanstalk/hooks/appdeploy/post/99_migrate.sh && chmod +x /opt/elasticbeanstalk/hooks/appdeploy/post/99_migrate.sh"
    leader_only: true

这将在正确的目录中创建一个部署后脚本,并且仅在领导者上。

这对我来说非常有效,但请注意,钩子目录是未记录的功能

【讨论】:

【参考方案3】:

container_commands 不在 docker 容器中执行。它们直接在 ec2 实例上执行。 目前我正在使用docker exec 进行迁移。由于相关的 docker 容器是最后一个启动的,我使用 docker ps -a --no-trunc -q | head -n 1 来获取容器 ID。

最后我的 setup.config 看起来像这样

container_commands:
  01syncdb:
    command: "docker exec `docker ps -a --no-trunc -q | head -n 1` /var/app/bin/python /var/app/manage.py syncdb --noinput  &>> /tmp/deploy.log"
    leader_only: true
  02migrate:
    command: "docker exec `docker ps -a --no-trunc -q | head -n 1` /var/app/bin/python /var/app/manage.py migrate --noinput  &>> /tmp/deploy.log"
    leader_only: true

我希望这也能解决您的问题。

【讨论】:

刚刚阅读:forums.aws.amazon.com/ann.jspa?annID=2982 我们本可以省去麻烦... 我试过这个,但我注意到它得到的是我的旧容器而不是我的新容器!有没有其他人看到这个问题?我正在尝试稍微修改但等效的命令:"CONTAINER=`docker ps -a --no-trunc | grep aws_beanstalk | cut -d' ' -f1 | head -1` &amp;&amp; docker exec $CONTAINER python3 manage.py migrate" 这可行,但将在当前版本上执行命令,而不是像@MrCols 所说的暂存版本(当前正在部署的版本)。 nkhumphreys 提供的解决方案似乎可以在新部署的版本上解决问题。

以上是关于Django AWS Elastic Beanstalk 迁移数据库的主要内容,如果未能解决你的问题,请参考以下文章

Django AWS Elastic Beanstalk 迁移数据库

AWS Elastic BeansTalk Django cronjob 发布请求返回 403 错误

在 AWS Elastic Beanstalk 上设置 Django:未找到 WSGIPath

如何设置运行 Django 的 AWS Elastic Beanstalk Docker 平台?

使用环境变量在 AWS Elastic Beanstalk 上使用 django 运行 celery

通过 AWS Elastic Beanstalk 部署 Django 应用程序会破坏 CSS 路径