sql - PostgreSQL 将列类型从 DATERANGE 更改为 TSTZRANGE 并迁移数据

标签 sql postgresql

我们正在将 run_dates 列(根据请求)从 daterange 更改为 tstzrange,该列包含几个月的测试数据。本质上我们想要迁移!

我正在运行下面的脚本,灵感来自 postgreSQL alter column data type to timestamp without time zone而且不得不承认,我的SQL背景基本没什么

-- Create a temporary TIMESTAMP column
ALTER TABLE table_name ADD COLUMN run_dates_holder TSTZRANGE NULL;

-- Copy casted value over to the temporary column
UPDATE table_name SET run_dates_holder = run_dates::TSTZRANGE;

-- Modify original column using the temporary column
ALTER TABLE table_name ALTER COLUMN run_dates TYPE
TSTZRANGE USING run_dates_holder;

-- Drop the temporary column (after examining altered column values)
ALTER TABLE table_name DROP COLUMN run_dates_holder;

不幸的是......这些类型不能自然翻译。

sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) cannot cast type daterange to tstzrange 

psycopg2.ProgrammingError: cannot cast type daterange to tstzrange
LINE 5: ...ble_name SET run_dates_holder = run_dates::TSTZRANG...

有没有人成功地将日期范围迁移到 tstzrange?

作为备份,我们可以删除 daterange 列并重新创建为 tstzrange,因为这只会影响测试数据。对团队来说不太理想。值得一试,我认为这里的解决方案至少对 future 的“从日期范围到 tstzrange”的迁移者来说是值得的,因为我没有找到关于此事的其他文档/资源

最佳答案

您不能只将日期范围转换为 tstzrange。使用lower() and upper()提取 daterangeupper_inc() and lower_inc() 的边界提取它们的包容性,并构造一个新的 tstzrange

UPDATE table_name
SET run_dates_holder=tstzrange(
  lower(run_dates), upper(run_dates),
  concat(
    CASE WHEN lower_inc(run_dates) THEN '[' else '(' END,
    CASE WHEN upper_inc(run_dates) THEN ']' ELSE ')' END)
  );

关于sql - PostgreSQL 将列类型从 DATERANGE 更改为 TSTZRANGE 并迁移数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60404546/

相关文章:

php - 我的更新 cade 有什么问题吗?

sql - 我如何获得SQL中多列总和的最大值?

postgresql - 从主机连接到 docker 容器中的 postgres

php - PHP检查数组的IP,在SQL数据库?

php - SQL不更新表

sql - 如何检查 TOAST 是否在 postgres 中的特定表上工作

node.js - sequelize 中不区分大小写的搜索

postgresql - 仅允许 postgres 用户列表角色

sql - 获取 postgresql EXPLAIN ANALYZE 作为列

java - 将 ResultSet 中的数据添加到 jTable