我有一个django项目,我正在按照这个CharField对queryset进行排序:
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"作为CREATE DATABASE选项之一重新创建数据库。不过,我不建议这样做,因为这会导致用户认为真正的自然语言文本排序顺序错误。
相反,请按列进行更改,例如。

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表示字节顺序排序。
有一张Django的COLLATE support票,几乎是icontains can be case-sensitive on MySQL的翻版。它似乎无限期地萎靡不振。我添加了一个注释,强烈鼓励将COLLATE的实现作为解决问题的正确方法。

关于django - 在Django项目中排序时,PostgreSQL忽略〜字符,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32684946/

10-14 11:24
查看更多