簡體   English   中英

Django原始SQL查詢有格式字符和字符串插值的麻煩

[英]Django raw SQL query trouble with format characters and string interpolation

在我的Django應用程序中,我需要生成如下的MySQL查詢:

SELECT * FROM player WHERE (myapp_player.sport_id = 4 AND (myapp_player.last_name LIKE 'smi%'))
UNION
SELECT * FROM player WHERE (myapp_player.sport_id = 4 AND (myapp_player.first_name LIKE 'smi%'));

我無法將Q對象與__istartswith過濾器一起使用,因為Django ORM生成的查詢不使用UNION,並且運行速度比上面的UNION查詢慢至少40倍。 對於我的應用程序,這種性能是不可接受的。

所以我正在嘗試這樣的事情:

Player.objects.raw("SELECT * FROM myapp_player WHERE (sport_id = %%s AND (last_name LIKE '%%s%')) UNION SELECT * FROM sports_player WHERE (sport_id = %%s AND (first_name LIKE '%%s%'))", (sport.id, qword, sport.id, qword))

我為長篇單行道歉,但我想避免在嘗試調試此類問題時使用三引號字符串。

當我執行或重新執行此queryset對象時,我得到如下異常:

*** ValueError: unsupported format character ''' (0x27) at index 133

這是單引號中的單引號,而不是三引號。 如果我擺脫了LIKE子句的單引號,那么我會得到一個關於LIKE子句之后的close-paren)字符的類似異常。

顯然Django和MySQL不同意這個查詢的正確語法,但是有一種語法可以兼顧兩者嗎?

最后,我不確定我的%% s字符串插值語法是否正確。 Django文檔建議我應該能夠在raw()的參數中使用常規%s語法,但是有幾個在線資源建議使用%% s或? 作為原始SQL中字符串插值的占位符。

衷心感謝您對這個問題的一點清晰度!

我讓它像這樣工作:

qword = word + '%'
Player.objects.raw("SELECT * FROM myapp_player WHERE (sport_id = %s AND (last_name LIKE %s)) UNION SELECT * FROM myapp_player WHERE (sport_id = %s AND (first_name LIKE %s))", (sport.id, qword, sport.id, qword))

除了%s似乎是參數化原始查詢的正確方法之外,這里的關鍵是在調用raw()之前將%通配符添加到LIKE子句並從LIKE子句周圍排除單引號。 盡管LIKE子句周圍沒有引號,但最終發送到MySQL服務器的查詢中會出現引號。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM