问题:
在本地,我使用Skaffold(Kubernetes)来热重新加载我的代码的客户端和服务器端。当我关闭它时,它会删除我的服务器pod,包括我的/ migrations /文件夹,因此与我的数据库alembic_version不同步。在生产时,我不是删除我的服务器pod,但是在部署时我正在重建docker镜像,导致我的/ migrations /文件夹被替换。
这个问题
如何处理这些迁移,以便我的数据库不会失去同步?
应用程序设置
Flask / Python API并使用Flask Migrate。对于那些不熟悉的人,它的作用是创建一个包含5a7b1a44a69a_.py
等版本文件的迁移文件夹。在该文件的内部是def upgrade()
和downgrade()
来操纵数据库。它还记录了postgres pod中alembic_version表的修订版和down_revision引用。
Kubernetes和Docker设置
我有一个服务器pod和postgres pod。我登录到服务器pod的shell以运行migrate命令。它在docker容器内创建版本文件并更新db。
要显示问题的分步示例:
最后的笔记
我以前做的pre-docker / kubernetes是在本地运行的,我会将迁移版本文件提交到我的repo。它在所有环境中同步,因此每个人的回购都在同一个alembic_version上。我已经考虑创建一个单独的,永远在线的“迁移 - 部署”窗格,它是另一个烧瓶实例,因此它永远不会丢失/ migrations /文件夹。然而,这似乎是一个非常糟糕的解决方案。
希望获得最佳实践或想法!
我找到了解决这个问题的方法。在其他人确认这是否是一个好方法之前,我不会将其设置为正确的答案。
基本上,我所做的是创建一个永久卷声明。在服务器部署中,我将迁移/文件夹连接到该持久卷。这样,无论何时删除pod,迁移/文件夹都会保留并在pod重新启动后保持不变。
它在服务器部署中看起来像这样。
containers:
..........
volumeMounts:
- name: migrationstuff
mountPath: 'MyServerApplicationDirectory/migrations'
volumes:
- name: migrationstuff
persistentVolumeClaim:
claimName: migrate-pvc
PVC看起来像这样:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: migrate-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
对于那些决定采用这种方法进行烧瓶迁移的人来说,有一个棘手的“鸡或鸡蛋”问题。运行flask db init时,它会创建包含一些内容的迁移/文件夹。但是,如果有一个PVC创建空迁移/文件夹,那么flask migrate已经认为该文件夹存在。你不能用rmdir删除文件夹,因为它有一个工作过程。但是,您需要将flask migrate命令的内容放入空迁移/文件夹中.....
我找到的诀窍是:
python flask db init --directory migration
mv migration/* migrations/
这会将您需要的所有文件初始化为新的“迁移”文件夹。然后,将其全部复制到迁移/文件夹中,以便从那时起保留。如果省略--directory标志,Flask migrate会自动查找该文件夹。
然后删除迁移文件夹rmdir migration
(或者等到你的pod重新启动,在这种情况下它将会消失)。
您现在拥有适当的迁移/文件夹,其中包含所有内容。当您关闭烧瓶舱并重新启动时,PVC将填充的迁移/文件夹注入到容器中。我现在可以升级/降级。只是要小心不要删除pvc!