在我的 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 对象来 OR 一起 __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))
我为冗长的单行表示歉意,但我想在尝试调试此类问题时避免使用三引号字符串。
当我执行或 repr 这个查询集对象时,我得到如下异常:
*** ValueError: unsupported format character ''' (0x27) at index 133
那是单引号中的单引号,而不是三引号。如果我去掉 LIKE 子句周围的单引号,那么我会得到关于 LIKE 子句后面的 close-paren ) 字符的类似异常。
显然 Django 和 MySQL 不同意这个查询的正确语法,但有没有一种语法对两者都适用?
最后,我也不确定用于字符串插值的 %%s 语法是否正确。Django 文档建议我应该能够在 raw() 的参数中使用常规的 %s 语法,但是一些在线资源建议使用 %%s 或 ? 作为原始 SQL 中字符串插值的占位符。
我真诚地感谢您对这个问题的一点点澄清!