如何构建一个 Python 比较器来按照 PostgreSQL 的方式对字符串进行排序?
How to build a Python comparator that sorts strings the way PostgreSQL does?
这个问题与this question基本相同,除了Python。
我希望查询 PostgreSQL 数据库中按电子邮件地址列排序的行,然后在 Python 中执行依赖于该排序的操作。
我正在查询的数据库正在使用 en_US.UTF8
排序规则,通过一些测试,我发现它对于电子邮件中的 @
符号有一些特殊的行为地址:
mydb=> SELECT '0' < '@';
?column?
----------
f
(1 row)
mydb=> SELECT '0' < '@0';
?column?
----------
t
(1 row)
This answer 表明某些排序规则可能会忽略 @
符号,但如果是这种情况,我会期望第二个查询出现 t
。
尽管 Python 提供了一个 locale module, that module has inconsistent behavior on some platforms,所以我似乎无法为此目的使用该模块。
根据该报告,我尝试了使用 PyICU package 的建议,这似乎很有希望:
>>> import icu
>>> collator = icu.Collator.createInstance()
>>> collator.getLocale()
<Locale: en_US>
>>> collator.getSortKey('0') < collator.getSortKey('@')
False
>>> collator.getSortKey('0') < collator.getSortKey('@0')
False
但如您所见,在上次比较中,它产生的顺序与 postgres 不同。
我试过为查询指定不同的排序规则,例如:
SELECT email COLLATE posix FROM mytable ORDER by email;
但这会导致错误:collation "posix" for encoding "UTF8" does not exist
。我也尝试了 "en-us-x-icu"
的排序规则,但也不存在。
是否有任何方法可以按照 Python 程序可以依赖的顺序从 PostgreSQL 中可靠地查询一列电子邮件地址,方法是调整查询的排序规则或采用默认排序规则在 Python?
在 Postgres 中使用 collate "C"
:
with test(test) as (
values ('@'), ('@0'), ('0')
)
select test
from test
order by test collate "C"
test
------
0
@
@0
(3 rows)
Python:
>>> test = ['@', '@0', '0']
>>> test.sort()
>>> test
['0', '@', '@0']
这个问题与this question基本相同,除了Python。
我希望查询 PostgreSQL 数据库中按电子邮件地址列排序的行,然后在 Python 中执行依赖于该排序的操作。
我正在查询的数据库正在使用 en_US.UTF8
排序规则,通过一些测试,我发现它对于电子邮件中的 @
符号有一些特殊的行为地址:
mydb=> SELECT '0' < '@';
?column?
----------
f
(1 row)
mydb=> SELECT '0' < '@0';
?column?
----------
t
(1 row)
This answer 表明某些排序规则可能会忽略 @
符号,但如果是这种情况,我会期望第二个查询出现 t
。
尽管 Python 提供了一个 locale module, that module has inconsistent behavior on some platforms,所以我似乎无法为此目的使用该模块。
根据该报告,我尝试了使用 PyICU package 的建议,这似乎很有希望:
>>> import icu
>>> collator = icu.Collator.createInstance()
>>> collator.getLocale()
<Locale: en_US>
>>> collator.getSortKey('0') < collator.getSortKey('@')
False
>>> collator.getSortKey('0') < collator.getSortKey('@0')
False
但如您所见,在上次比较中,它产生的顺序与 postgres 不同。
我试过为查询指定不同的排序规则,例如:
SELECT email COLLATE posix FROM mytable ORDER by email;
但这会导致错误:collation "posix" for encoding "UTF8" does not exist
。我也尝试了 "en-us-x-icu"
的排序规则,但也不存在。
是否有任何方法可以按照 Python 程序可以依赖的顺序从 PostgreSQL 中可靠地查询一列电子邮件地址,方法是调整查询的排序规则或采用默认排序规则在 Python?
在 Postgres 中使用 collate "C"
:
with test(test) as (
values ('@'), ('@0'), ('0')
)
select test
from test
order by test collate "C"
test
------
0
@
@0
(3 rows)
Python:
>>> test = ['@', '@0', '0']
>>> test.sort()
>>> test
['0', '@', '@0']