2012-03-03 10 views
7

PostgreSQL 8.4とUbuntu 10.04は、スウェーデン語アルファベットのWとVのソート方法を更新できません。つまり、それはまだ、この(スウェーデンの発注のための古い定義)のように同じ文字としてそれらを注文です:ロケールを考慮したタプルのリストをソートする(スウェーデン語の注文)

  • Vbの
  • Wcが
  • Vdの

それは(あるべきスウェーデンの注文の新しい定義):

  • Vb
  • Vdは
  • Waが
  • Wcの

私が構築してるのPython/Djangoのウェブサイトに正しくこれを注文する必要があります。私は、* values_list *を使用してDjango QuerySetから作成されたタプルのリストを注文する様々な方法を試みました。しかし、スウェーデン語であるため、å、ä、öの文字を正しく並べ替える必要があります。

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

、私がしたいことは、これらのようにV/Wとå両方の組み合わせです:今、私はどちらか一方または両方の両方ではない...

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 

他の方法の例が与える持っています、ä、ö順序が正しい。より正確には。私はを希望します。にロケールを尊重してください。各タプルで2番目の項目(オブジェクトID)を使用することで、Djangoで正しいオブジェクトを取得できました。

私はこれが可能であることを疑い始めていますか? PostgreSQLをより新しいバージョンにアップグレードして、照合をよりうまく処理し、Djangoで生のSQLを使用することは可能でしょうか?

+0

私はPostgres 8.4とUbuntu 10.04 LTSがうまくいくはずだと思います。あなたのクラスタはどのロケールに設定されていますか?コマンド "show lc_collat​​e;"でこれを知ることができます。 –

+0

私は、ロケールがクラスタ(sv_SE)に対して正しいことを述べるべきでした。私はこれを以前に変更して、å、ä、öが正しくソートされるようにしなければなりませんでした。 – daru

答えて

8

Ubuntu-10.04であなたの例でLC_ALL=sv_SE.UTF-8 sortを実行すると、Vbの前にWa(「古い方法」)が出てくるので、Ubuntuは「新しい方法」に同意していないようです。 PostgreSQLはオペレーティングシステムに依存しているため、同じlc_collat​​eが与えられたOSとまったく同じように動作します。

実際にこの特定のソートの問題に関する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

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) 
関連する問題