Django/PostgreSQL varchar到UUID

std*_*ave 5 python sql django postgresql varchar

我正在尝试将项目从Django 1.7更新到1.9.不幸的是UUIDfield,它使用了varchar内部使用的django-extensions .我正在尝试将这些字段更改uuid为数据库中的类型.

我已经创建了一个自定义迁移,告诉Django迁移将使用自己的SQL来完成它.当我这样做时(列被命名guid)我的问题出现了:

alter table tablename alter column guid type uuid using guid::uuid;
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

错误:运算符类"varchar_pattern_ops"不接受数据类型uuid

我对PostgreSQL并不熟悉,而且有点过头了.我可以创建一个CAST或其他东西来解决这个问题吗?我无法弄明白我的意思.

我试图使用这里脚本,它应该处理索引依赖,但我真的在我脑海里.

Erw*_*ter 3

type uuid在您的 DDL 语句中是 的简写SET DATA TYPE uuid手册:

SET DATA TYPE

这种形式改变表的列的类型。通过重新分析最初提供的表达式,涉及该列的索引和简单表约束将自动转换为使用新的列类型。[...]

varchar_pattern_ops是一个运算符类uuid,如果您在任何索引中使用此运算符类,则会在错误消息中提到该运算符类。通常是为了实现更快的排序、模式匹配和范围条件。

要修复此问题,请删除冲突的索引,更改数据类型,然后在不使用特殊运算符类的情况下重新创建索引 -如果您仍然需要它们。

但是,一些使用varchar_pattern_ops索引的典型查询将停止使用数据类型uuid而不是varchar. 就像模式匹配一​​样:

确保也修复任何此类查询。

@fl0cke指出了一个相关的答案:

我建议走一条稍微不同的路线。删除索引、更改数据类型然后创建新索引会更便宜-如果它仍然有用的话。

DROP INDEX tbl_guid_varchar_pattern_ops_idx;

ALTER TABLE tbl ALTER COLUMN guid TYPE uuid USING guid::uuid;

CREATE INDEX tbl_guid_idx ON tbl (guid);
Run Code Online (Sandbox Code Playgroud)

如何找到违规索引?

我需要弄清楚如何检查现有的索引。

在现代版本的 Postgres 中,您可以使用 psql 获取表的现有索引\d tbl

要获取CREATE INDEX给定表的所有完整语句:

SELECT pg_get_indexdef(indexrelid) || ';' AS idx
FROM   pg_index
WHERE  indrelid = 'public.tbl'::regclass;  -- optionally schema-qualified
Run Code Online (Sandbox Code Playgroud)

要仅获取使用的varchar_pattern_ops

SELECT pg_get_indexdef(i.indexrelid) || ';' AS idx
FROM   pg_index i
JOIN   pg_opclass o ON o.oid = ANY (i.indclass)
WHERE  i.indrelid = 'public.big'::regclass
AND    o.opcname = 'varchar_pattern_ops';
Run Code Online (Sandbox Code Playgroud)

细节: