2012-01-26 10 views
6

Korzystanie z Django 1.3x.Czy mogę łatwo przesadzić z Django ORM 'iexact', aby użyć LOWER() zamiast UPPER()?

Obecnie mam bardzo, bardzo duży i bardzo, bardzo aktywny zestaw danych Postgres, który ma ważną kolumnę indeksowaną jako lower(column).

Właśnie zdałem sobie sprawę, że niektóre typowe zapytania były dość powolne, ponieważ ORM Django generuje zapytanie do pola jako blah = UPPER(column), kiedy używam iexact do dopasowania tego pola.

Czy istnieje prosty sposób zmuszenia ORM do użycia lower() zamiast tego, czy muszę wstawić do surowego SQL dla tego?

Dzięki!

[strona pytanie za komentarze: Czy istnieje dobry powód, naprzeciwko, aby wykorzystali upper() na indeksie zamiast lower()?]

Odpowiedz

7

interesująca sytuacja tutaj. Nigdy tak naprawdę nie przestałem o tym myśleć. Wygląda na to, że do wyszukiwania UPPER dla iexact wyszukiwań wprowadzono ponownie w revision 8536, w odpowiedzi na ticket 3575, prawie trzy lata temu. Wcześniej Django używał ILIKE dla tego typu wyszukiwań.

Przejrzałem kod backendu i jedyne, co mogę znaleźć, wskazuje na to, że z jakiegokolwiek powodu UPPER vs LOWER wydaje się, że Oracle domyślnie stosuje wielkie litery w przetwarzaniu danych nieodczuujących wielkości liter. Ponieważ inne są agnostyczne, wydaje się, że Django zdecydowało się na domyślne zabezpieczenie na UPPER, aby pokryć wszystkie bazy.

Innym wrażeniem, jakie dostałem od patrzenia na kod źródłowy, było to, że nie zamierzasz obejść się używając UPPER. Dosłownie w każdym miejscu, a nie tylko wtedy, gdy faktycznie wyszukuje bazę danych. Rozszerzenia ciągów Pythona upper są również często używane.

Powiedziałbym, że najlepiej jest po prostu utworzyć indeks z numerem upper(column) lub zamiast niego i wypić drinka.

+0

Chris, dzięki za odpowiedź! Natknąłem się również na te bilety, ale nie widziałem żadnej poważnej dyskusji na temat, dlaczego nagle zmieniło się na 'upper()'. Twój wgląd w bitwie Oracle jest najbardziej słyszałem. Jest to proste zapytanie, więc przypuszczam, że użyję po prostu '.raw()' tutaj. Dzięki wielkie! –

3

Spróbuj .extra() przed pójściem do .raw()

MyModel.objects.extra(where=["lower(mycol)=%s"], params=['foo']) 
Powiązane problemy