2012-03-03 52 views
7

显然,PostgreSQL 8.4和Ubuntu 10.04无法处理更新的方式来对W和V进行瑞典字母排序。也就是说,它仍然命令他们像这样(旧定义为瑞典排序)相同的字母:考虑区域设置的元组排序列表(瑞典语排序)

  • Vb的
  • 厕所
  • Vd的

它应该是(瑞典定购的新定义):

  • Vb
  • Vd的
  • 厕所

我需要正确订购此为一个Python/Django的网站我建立。我已经尝试过各种方法来订购使用* values_list *从Django QuerySet创建的元组列表。但是因为它也是瑞典语ä,ä和ö字母需要正确排列。现在我有一个或其他方式都不能同时..

list_of_tuples = [(u'Wa', 1), (u'Vb',2), (u'Wc',3), (u'Vd',4), (u'Öa',5), (u'äa',6), (u'Åa',7)] 

print '########## Ordering One ##############' 
ordered_list_one = sorted(list_of_tuples, key=lambda t: tuple(t[0].lower())) 
for item in ordered_list_one: 
    print item[0] 

print '########## Ordering Two ##############' 
locale.setlocale(locale.LC_ALL, "sv_SE.utf8") 
list_of_names = [u'Wa', u'Vb', u'Wc', u'Vd', u'Öa', u'äa', u'Åa'] 
ordered_list_two = sorted(list_of_names, cmp=locale.strcoll) 
for item in ordered_list_two: 
    print item 

的例子给出了:

########## Ordering One ############## 
Vb 
Vd 
Wa 
Wc 
äa 
Åa 
Öa 
########## Ordering Two ############## 
Wa 
Vb 
Wc 
Vd 
Åa 
äa 
Öa 

现在,我要的是它们的组合,这样既V/W和,ä,ö排序是正确的。更确切地说。我想订购一个尊重区域设置。然后在每个元组中使用第二项(对象ID),我可以在Django中获取正确的对象。

我开始怀疑这是可能的吗?将PostgreSQL升级到更好的版本可以更好地处理排序规则,然后在Django中使用原始SQL吗?

+0

我认为Postgres 8.4和Ubuntu 10.04 LTS应该没问题。您的集群设置了哪些区域设置?你可以通过命令“show lc_collat​​e;”来告诉它 – 2012-03-03 22:12:19

+0

我应该提到该区域对于群集(sv_SE)是正确的。我必须早一点改变这个才能使å,ä和ö被正确排序。 – daru 2012-03-04 08:27:39

回答

8

当您在Ubuntu-10.04上运行LC_ALL=sv_SE.UTF-8 sort时,它会在Vb之前出现(“旧方式”),所以Ubuntu似乎并不认同“新方式”。 由于PostgreSQL依赖于此操作系统,它的行为将与给定相同lc_collat​​e的操作系统相同。

debian glibc中实际上有一个补丁涉及到这个特定的排序问题: http://sourceware.org/bugzilla/show_bug.cgi?id=9724 但它被反对并没有被接受。如果您只需要在您管理的系统上执行此操作,则仍然可以将修补程序的更改应用于/ usr/share/i18n/locales/sv_SE,并通过运行locale-gen sv_SE.UTF-8重新生成se_SV区域设置。或者更好的是,创建自己的替代语言环境,以避免与原文混淆。

+0

好像我正试图解决我在使用的堆栈错误末端的问题。我完全控制了主机,所以使用该补丁没有问题。非常感谢你! – daru 2012-03-04 08:24:15

0

该解决方案很复杂,因为key = locale.strxfrm可以正常工作 单列表和字典,但不包含列表列表或 元组列表。

Py2 - > Py3的变化:使用locale.setlocale(locale.LC_ALL,'') 和key ='locale.strxfrm'(而不是'cmp = locale.strcoll')。

list_of_tuples = [('Wa', 1), ('Vb',2), ('Wc',3), ('Vd',4), ('Öa',5), ('äa',6), ('Åa',7)] 

def locTupSorter(uLot): 
    "Locale-wise list of tuples sorter - works with most European languages" 
    import locale 
    locale.setlocale(locale.LC_ALL, '') # get current locale 

    dicTups = dict(uLot)   # list of tups to unsorted dictionary 
    ssList = sorted(dicTups, key=locale.strxfrm) 
    sLot = [] 
    for i in range(len(ssList)): # builds a sorted list of tups 
     tfLot =() 
     elem = ssList[i]   # creates tuples for list 
     tfLot = (elem, dicTups[elem]) 
     sLot.append(tfLot)  # creates sorted list of tuples 
    return(sLot) 


print("list_of_tuples=\n", list_of_tuples) 
sortedLot = locTupSorter(list_of_tuples) 
print("sorted list of tuples=\n",sortedLot)