2012-01-26 8 views
6

Utilizzo di Django 1.3x.Posso superare facilmente Django ORM 'iexact' per usare LOWER() invece di UPPER()?

Attualmente ho un dataset Postgres molto, molto grande e molto, molto attivo che ha una colonna importante indicizzata come .

Ho appena realizzato che alcune query comuni erano piuttosto lente perché l'ORM di Django sta generando una query per il campo come blah = UPPER(column) quando sto usando iexact per abbinare quel campo.

C'è un modo semplice per forzare l'ORM a utilizzare lower() invece, o devo passare a SQL raw per questo?

Grazie!

[domanda lato per i commenti: C'è una buona ragione, di fronte, di aver utilizzato upper() sull'indice, piuttosto che lower()?]

risposta

7

situazione interessante qui. Non mi ero mai fermato a pensarci prima. Sembra che l'utilizzo di UPPER per le ricerche iexact sia stato reintrodotto in revision 8536, in risposta a ticket 3575, quasi tre anni fa. Prima che Django avesse usato ILIKE per questi tipi di ricerche.

ho guardato attraverso il codice backend e l'unica cosa che può trovare che i punti di qualsiasi ragione per UPPER vs LOWER sembra essere che Oracle di default in maiuscolo nel suo trattamento dei dati case-insensitive. Dato che gli altri sono agnostici, sembra che Django abbia deciso di impostare il valore predefinito su UPPER per coprire tutte le basi.

L'altra impressione che ho avuto dal codice sorgente è che non si è in grado di spostarsi utilizzando UPPER. È letteralmente dappertutto e non solo quando si effettua una query sul database. Anche l'estensione di stringa upper di Python viene utilizzata abbastanza frequentemente.

Direi che la soluzione migliore è semplicemente creare un indice con upper(column) o anziché, e andare a bere qualcosa.

+0

Chris, Grazie per la risposta! Mi sono imbattuto anche in quei biglietti, ma non ho visto nessuna discussione importante sul perché improvvisamente cambiato in 'upper()'. La tua opinione su Oracle bit è la più che ho sentito. Questa è una semplice domanda, davvero, quindi suppongo che userò semplicemente '.raw()' qui. Grazie mille! –

3

Prova .extra() prima di andare a .raw()

MyModel.objects.extra(where=["lower(mycol)=%s"], params=['foo']) 
Problemi correlati