问题:
在本地,我使用Skaffold(Kubernetes)来热重载代码的客户端和服务器端。当我关闭它时,它将删除我的服务器Pod,包括我的/ migrations /文件夹,因此与我的数据库alembic_version不同步。在生产中,我没有删除服务器Pod,但是在部署时正在重建docker映像,这导致替换了/ migrations /文件夹。
问题
我该如何处理这些迁移,以免数据库不同步?
应用程序设置
Flask / Python API并使用Flask Migrate。对于那些不熟悉的人,它要做的是创建一个带有5a7b1a44a69a_.py
之类的版本文件的迁移文件夹。该文件的内部是def upgrade()
和downgrade()
来操作数据库。它还在我的postgres窗格中记录了alembic_version表的修订和down_revision参考。
Kubernetes和Docker设置
我有一个服务器容器和postgres容器。我登录到服务器容器的外壳以运行迁移命令。它会在docker容器内创建版本文件并更新数据库。
逐步展示该问题的示例:
最终提示
我以前在docker / kubernetes之前所做的工作是在本地运行的,我会将那个迁移版本文件提交到我的仓库中。它已在所有环境中同步,因此每个人的回购都在同一alembic_version上。我考虑过创建一个单独的,始终在线的“ migrations-deployment”吊舱,它是flask的另一个实例,因此它永远不会丢失/ migrations /文件夹。但是,这似乎是一个非常糟糕的解决方案。
希望获得最佳实践或想法!
答案 0 :(得分:0)
我想出了一种解决方法。在其他人确认这是一个好方法之前,我不会将其设置为正确的答案。
基本上,我所做的是创建一个持久量声明。在服务器部署内部,我将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时,它会在其中创建包含某些内容的migrations /文件夹。但是,如果有一个PVC创建了一个空的migrations /文件夹,则烧瓶迁移已经认为该文件夹存在。您也无法使用rmdir删除该文件夹,因为该文件夹上有正在运行的进程。但是,您需要将flask migration init命令的内容放入空的migrations /文件夹中.....
我发现的窍门是:
python flask db init --directory migration
mv migration/* migrations/
这会将您需要的所有文件初始化为一个新的“迁移”文件夹。然后,将其全部复制到migrations /文件夹中,然后再继续保存。如果省略--directory标志,则Flask migration会自动查找该文件夹。
然后删除迁移文件夹rmdir migration
(或等到pod重新启动后再消失)。
您现在拥有一个包含所有内容的适当的migrations /文件夹。当关闭烧瓶吊舱并重新启动时,PVC注入将迁移文件/文件夹填充回吊舱。我现在可以升级/降级。只需注意不要删除pvc!