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` && 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 平台?