在Django项目中排序时postgresql忽略〜字符

时间:2015-09-20 22:26:10

标签: django postgresql sorting django-queryset

我有一个django项目,我按照这个CharField对查询集进行排序:

name = models.CharField(max_length=50, unique=True)

在我的默认django db.sqlite3服务器上,它按我的意愿排序(根据ASCII值),其中名称以波形符〜字符开头的对象出现在列表的底部:

item
jitem
litem
~kitem

但在我的生产postgresql服务器上,它们看起来像这样:

item
jitem
~kitem
litem

并且在排序时似乎忽略了波浪号。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

这是正常行为。您的默认排序规则是在排序时忽略标点符号和其他特殊字符的排序规则。

如果要根据当前文本编码中的序数值进行简单排序,其中使用COLLATE "C"。这可以应用于数据库,列,索引或查询级别。

您无法在数据库范围内更改现有数据库的排序规则,但可以更改列和索引。

如果要为整个数据库更改它,则需要pg_dump数据库,删除数据库,然后使用COLLATE "C"作为CREATE DATABASE之一重新创建数据库}选项。但是,我建议这样做,因为它会导致用户认为错误对真实自然语言文本的排序顺序。

相反,请按列进行更改,例如

ALTER TABLE collate_demo ALTER COLUMN test_col TYPE text COLLATE "C";

(保持与以前相同的类型,只需更改排序规则)

请注意,您也可以为单个查询指定所需的排序规则,但Django可能不允许您这样做。 E.g。

SELECT * FROM collate_demo ORDER BY test_col COLLATE "C";

SELECT * FROM collate_demo WHERE test_col > 'A' COLLATE "C" ORDER BY test_col COLLATE "C";

COLLATE子句仅适用于特定的比较运算符或其指定的ORDER BY。它不是整个查询的修饰符。

请注意,即使两个字符串根据国家语言校对规则相同,它们也永远不会被PostgreSQL报告为相等。如果自然语言排序规则它们排序相同但它们在字节方面不相同,则按utf-8表示字节顺序进行排序。

COLLATE support打开了一张Django票证,该票据已被关闭,几乎与icontains can be case-sensitive on MySQL重复。它似乎无限期地衰弱了。我添加了一条强烈鼓励实施COLLATE作为解决问题的正确方法的说明。