如何从 Google Cloud SQL 中的 pg_enum table 中删除枚举标签?
How can I remove an enum label from pg_enum table in Google Cloud SQL?
我最近构建了一个 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 是一项托管服务,它不向像我这样的客户提供超级用户权限。有没有其他方法可以获得此迁移 运行?
我也尝试过 运行 云构建过程,但也失败并出现以下错误: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 不支持从枚举中删除值。您只能添加新的或重命名现有的。
虽然它可能通过修改系统目录在某种程度上可靠地工作,但即使这样也没有得到官方支持并且出于某种原因需要超级用户权限 - 所以没有办法就没有办法做到这一点。
执行您想执行的操作的受支持方法是重新创建没有值的类型。
CREATE TYPE new_enum AS ENUM('a','b','c');
ALTER TABLE table_using_old_enum
ALTER COLUMN colum_using_old_enum
SET DATA TYPE new_enum
USING colum_using_old_enum::text::new_enum;
DROP TYPE old_enum;
ALTER TYPE new_enum RENAME TO old_enum;
这显然只有在 table_using_old_type
中没有条目仍设置为您要删除的值时才有效 - 您需要首先确保这一点,否则 USING
子句中的类型转换将失败对于这些值。
--
或者,您也可以只注释掉该查询 - 如果您已经知道几分钟后在稍后的迁移中该类型将被完全删除,那么如果该值一直保留到那时就不会造成问题.
我最近构建了一个 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 是一项托管服务,它不向像我这样的客户提供超级用户权限。有没有其他方法可以获得此迁移 运行?
我也尝试过 运行 云构建过程,但也失败并出现以下错误: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 不支持从枚举中删除值。您只能添加新的或重命名现有的。
虽然它可能通过修改系统目录在某种程度上可靠地工作,但即使这样也没有得到官方支持并且出于某种原因需要超级用户权限 - 所以没有办法就没有办法做到这一点。
执行您想执行的操作的受支持方法是重新创建没有值的类型。
CREATE TYPE new_enum AS ENUM('a','b','c');
ALTER TABLE table_using_old_enum
ALTER COLUMN colum_using_old_enum
SET DATA TYPE new_enum
USING colum_using_old_enum::text::new_enum;
DROP TYPE old_enum;
ALTER TYPE new_enum RENAME TO old_enum;
这显然只有在 table_using_old_type
中没有条目仍设置为您要删除的值时才有效 - 您需要首先确保这一点,否则 USING
子句中的类型转换将失败对于这些值。
--
或者,您也可以只注释掉该查询 - 如果您已经知道几分钟后在稍后的迁移中该类型将被完全删除,那么如果该值一直保留到那时就不会造成问题.