【发布时间】:2021-05-02 16:51:18
【问题描述】:
我有一个我最近构建的 Node 应用程序 (Express),它使用 Sequelize 连接到 PostgreSQL 实例。我刚刚将它部署到 GCP 并使用 Cloud SQL 来设置数据库。这工作得很好,应用程序正确连接到数据库实例。
但是,在运行迁移时,我得到了这个错误:permission denied for table pg_enum
这发生在我尝试从数据库中删除枚举值的单个迁移中:
module.exports = {
up: (queryInterface, Sequelize) =>
queryInterface.sequelize.query(
`DELETE FROM pg_enum WHERE enumlabel = 'to' AND enumtypid = (SELECT oid FROM pg_type WHERE typname = 'enum_Subscriptions_emailType')`
),
down: (queryInterface, Sequelize) =>
queryInterface.sequelize.query(`ALTER TYPE "enum_Subscriptions_emailType" ADD VALUE 'to';`)
}
我读过here,因为 Cloud SQL 是一项托管服务,它不会为像我这样的客户提供超级用户权限。还有其他方法可以让我运行此迁移吗?
我也尝试过运行 Cloud Build 进程,但同样失败并出现以下错误:ERROR: connect ENOENT /cloudsql/<project-id>:<project-region>:<db-instance>/.s.PGSQL.5432。作为参考,我的cloudbuild.yaml 文件如下所示:
steps:
- name: 'gcr.io/cloud-builders/yarn'
args: ['install']
- name: 'gcr.io/cloud-builders/yarn'
args: ['migrate']
- name: 'gcr.io/cloud-builders/gcloud'
args: ['app', 'deploy']
我的 package.json 脚本是:
"scripts": {
"start": "node index.js",
"migrate": "npx sequelize-cli db:migrate",
"dev": "set DEBUG=app:* && nodemon index.js",
"deploy": "gcloud builds submit --config cloudbuild.yaml ."
}
我还能做些什么来解决这个问题,以便我跟随这个迁移可以运行并且我的应用可以运行?
【问题讨论】:
-
PostgreSQL 不支持从枚举中删除单个值。 postgresql.org/docs/current/datatype-enum.html如果你真的需要这样做,你可以将所有使用枚举的列中的类型更改为文本,删除类型,重新创建没有值的类型并将列改回来。
-
感谢 Johannes - 但这是我几个月前所做的更改,它在我本地的 postgres 数据库上运行良好。但这似乎给了我关于 Cloud SQL 的问题——关于我能做什么的任何想法?在这之后,我实际上还有 18 个迁移要运行(巧合的是,这些未来的迁移之一实际上完全删除了枚举)
-
它在本地工作,但它不受 postgres 官方支持。修改系统目录总是有风险的——这就是为什么需要超级用户权限才能这样做。删除 enaum 值的可能工作流程已经在我的第一条评论中:重新创建类型。一种更短的方法是首先创建一个新类型,而不使用您要删除的值,使用不同的名称,然后更改所有列,然后重命名该类型。
-
我会比@JohannesH 更进一步。直接修改系统目录,即使是超级用户,也是一种可解雇的罪行。如果系统提供的命令无法完成任务(并且删除枚举条目是没有更改命令的条目),那么您需要很长的路要走。正如建议的那样,只需删除当前类型,是的,您需要更改每个引用。另一种选择是将值留在枚举中,但创建一个不允许该值的触发器。
-
谢谢 JohannesH。还有Belayer——我不知道修改这些有那么糟糕;会记住这一点。作为约翰内斯H。在他的回答中建议,我将注释掉这个迁移,因为我们会在未来的迁移中删除枚举。
标签: postgresql express enums database-migration google-cloud-sql