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

postgresql ignoring ~ character when sorting in Django project

我有一个 Django 项目,我在其中按此 CharField:

对查询集进行排序

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

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

item
jitem
litem
~kitem

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

item
jitem
~kitem
litem

排序时波浪号似乎被忽略了。

我该如何解决这个问题?

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

如果您想根据当前文本编码中的序号值对每个字符进行简单排序,请使用 COLLATE "C"。这可以应用于数据库、列、索引或查询级别。

您不能在整个数据库范围内更改现有数据库的排序规则,但是您可以更改列和索引。

如果您想为整个数据库更改它,您需要 pg_dump 数据库,删除数据库,然后使用 COLLATE "C" 作为 [=] 之一重新创建数据库16=] 选项。不过,我建议这样做,因为它会导致用户认为错误真实自然语言文本的排序顺序。

相反,在每列的基础上进行更改,例如

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

(保持之前的类型,只是更改排序规则)


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

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, which has been closed as almost a duplicate of icontains can be case-sensitive on MySQL 的 Django 门票开放。它似乎已经无限期地萎靡不振。我添加了一条注释,强烈鼓励实施 COLLATE 作为解决问题的正确方法。