我正在尝试将项目从 Django 1.7 更新到 1.9。不幸的是,它使用了内部使用 varchar
的 django-extensions UUIDfield
。我正在尝试将这些字段更改为数据库中的 uuid
类型。
我已经创建了一个自定义迁移,告诉 Django 迁移将使用它自己的 SQL 来完成。当我这样做时,我的问题就来了(该列名为 guid
):
alter table tablename alter column guid type uuid using guid::uuid;
我收到这个错误:
ERROR: operator class "varchar_pattern_ops" does not accept data type uuid
我真的不太熟悉 PostgreSQL,有点不知所措。我可以创建一个 CAST 或其他东西来解决这个问题吗?我不知道我会怎么做。
我正在尝试使用 script from here它应该处理索引依赖关系,但我真的在我的头上。
最佳答案
type uuid
在您的 DDL 语句中是 SET DATA TYPE uuid
的简写。 The manual:
SET DATA TYPE
This form changes the type of a column of a table. Indexes and simple table constraints involving the column will be automatically converted to use the new column type by reparsing the originally supplied expression. [...]
varchar_pattern_ops
是一个 operator class如果您有 uuid
在任何索引中使用此运算符类,则会在您的错误消息中提及。通常用于实现更快的排序、模式匹配和范围条件。
要解决问题,请删除冲突的索引,更改数据类型,然后在没有特殊运算符类的情况下重新创建索引 - 如果您仍然需要它们。
但是,一些使用 varchar_pattern_ops
索引的典型查询将停止使用数据类型 uuid
而不是 varchar
。喜欢模式匹配:
确保同时修复任何此类查询。
@fl0cke pointed out相关回答:
我建议采用稍微不同的路线。删除索引、更改数据类型并然后创建一个新索引(如果它仍然有用的话)的成本更低。
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);
如何找到违规索引?
I need to figure out how to examine the existent indices.
在现代版本的 Postgres 中,您可以在 psql 中使用 \d tbl
获取表的现有索引。
获取给定表的所有完整 CREATE INDEX
语句:
SELECT pg_get_indexdef(indexrelid) || ';' AS idx
FROM pg_index
WHERE indrelid = 'public.tbl'::regclass; -- optionally schema-qualified
使用 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';
详细信息:
关于python - Django/PostgreSQL varchar 到 UUID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35139818/