2012-01-26 21 views
6

Sử dụng Django 1.3x.Tôi có thể dễ dàng vượt qua Django ORM 'iexact' để sử dụng LOWER() thay vì UPPER() không?

Tôi hiện đang có bộ dữ liệu Postgres rất, rất lớn và rất, rất tích cực có cột quan trọng được lập chỉ mục là lower(column).

Tôi vừa nhận ra rằng một số truy vấn phổ biến khá chậm vì ORM Django đang tạo truy vấn cho trường là blah = UPPER(column) khi tôi đang sử dụng iexact để khớp với trường đó.

Có cách nào đơn giản để buộc ORM sử dụng lower() thay thế hay tôi cần phải thả vào SQL thô cho mục này?

Cảm ơn!

[bên câu hỏi cho ý kiến: Có một lý do chính đáng, bỏ qua, đã sử dụng upper() trên chỉ số, chứ không phải là lower()?]

Trả lời

7

tình huống thú vị ở đây. Tôi chưa bao giờ thực sự dừng lại để suy nghĩ về nó trước đây. Có vẻ như việc sử dụng số UPPER cho các tìm kiếm iexact được giới thiệu lại trong revision 8536, theo trả lời ticket 3575, gần ba năm trước. Trước đó Django đã sử dụng ILIKE cho các loại tìm kiếm này.

Tôi đã xem qua mã phụ trợ và điều duy nhất tôi có thể tìm thấy trỏ đến bất kỳ lý do nào cho UPPERLOWER dường như là mặc định của Oracle đối với chữ hoa trong việc xử lý dữ liệu không phân biệt chữ hoa chữ thường. Vì những người khác là bất khả tri, có vẻ như Django đã quyết định mặc định là UPPER để trang trải tất cả các cơ sở.

Ấn tượng khác mà tôi nhận được khi xem mã nguồn là bạn sẽ không sử dụng được UPPER. Đó là nghĩa đen tất cả các nơi và không chỉ khi thực sự truy vấn cơ sở dữ liệu. Phần mở rộng chuỗi upper của Python được sử dụng khá thường xuyên.

Tôi muốn đặt cược tốt nhất của bạn là chỉ cần tạo một chỉ mục với số upper(column) cũng như thay vì và đi uống.

+0

Chris, Cảm ơn câu trả lời của bạn! Tôi cũng đã xem qua những vé đó, nhưng không thấy bất kỳ cuộc thảo luận lớn nào về việc tại sao nó đột nhiên thay đổi thành 'upper()'. Cái nhìn sâu sắc của bạn về bit Oracle là thứ tôi đã nghe nhiều nhất. Đây là một truy vấn đơn giản, thực sự, vì vậy tôi cho rằng tôi sẽ chỉ sử dụng '.raw()' ở đây. Cám ơn rất nhiều! –

3

Hãy thử .extra() trước khi đi .raw()

MyModel.objects.extra(where=["lower(mycol)=%s"], params=['foo']) 
Các vấn đề liên quan