Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/sqlalchemy/dialects/mysql/expression.py: 54%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

41 statements  

1# dialects/mysql/expression.py 

2# Copyright (C) 2005-2025 the SQLAlchemy authors and contributors 

3# <see AUTHORS file> 

4# 

5# This module is part of SQLAlchemy and is released under 

6# the MIT License: https://www.opensource.org/licenses/mit-license.php 

7 

8from __future__ import annotations 

9 

10from typing import Any 

11 

12from ... import exc 

13from ... import util 

14from ...sql import coercions 

15from ...sql import elements 

16from ...sql import operators 

17from ...sql import roles 

18from ...sql.base import _generative 

19from ...sql.base import Generative 

20from ...util.typing import Self 

21 

22 

23class match(Generative, elements.BinaryExpression[Any]): 

24 """Produce a ``MATCH (X, Y) AGAINST ('TEXT')`` clause. 

25 

26 E.g.:: 

27 

28 from sqlalchemy import desc 

29 from sqlalchemy.dialects.mysql import match 

30 

31 match_expr = match( 

32 users_table.c.firstname, 

33 users_table.c.lastname, 

34 against="Firstname Lastname", 

35 ) 

36 

37 stmt = ( 

38 select(users_table) 

39 .where(match_expr.in_boolean_mode()) 

40 .order_by(desc(match_expr)) 

41 ) 

42 

43 Would produce SQL resembling: 

44 

45 .. sourcecode:: sql 

46 

47 SELECT id, firstname, lastname 

48 FROM user 

49 WHERE MATCH(firstname, lastname) AGAINST (:param_1 IN BOOLEAN MODE) 

50 ORDER BY MATCH(firstname, lastname) AGAINST (:param_2) DESC 

51 

52 The :func:`_mysql.match` function is a standalone version of the 

53 :meth:`_sql.ColumnElement.match` method available on all 

54 SQL expressions, as when :meth:`_expression.ColumnElement.match` is 

55 used, but allows to pass multiple columns 

56 

57 :param cols: column expressions to match against 

58 

59 :param against: expression to be compared towards 

60 

61 :param in_boolean_mode: boolean, set "boolean mode" to true 

62 

63 :param in_natural_language_mode: boolean , set "natural language" to true 

64 

65 :param with_query_expansion: boolean, set "query expansion" to true 

66 

67 .. versionadded:: 1.4.19 

68 

69 .. seealso:: 

70 

71 :meth:`_expression.ColumnElement.match` 

72 

73 """ 

74 

75 __visit_name__ = "mysql_match" 

76 

77 inherit_cache = True 

78 modifiers: util.immutabledict[str, Any] 

79 

80 def __init__(self, *cols: elements.ColumnElement[Any], **kw: Any): 

81 if not cols: 

82 raise exc.ArgumentError("columns are required") 

83 

84 against = kw.pop("against", None) 

85 

86 if against is None: 

87 raise exc.ArgumentError("against is required") 

88 against = coercions.expect( 

89 roles.ExpressionElementRole, 

90 against, 

91 ) 

92 

93 left = elements.BooleanClauseList._construct_raw( 

94 operators.comma_op, 

95 clauses=cols, 

96 ) 

97 left.group = False 

98 

99 flags = util.immutabledict( 

100 { 

101 "mysql_boolean_mode": kw.pop("in_boolean_mode", False), 

102 "mysql_natural_language": kw.pop( 

103 "in_natural_language_mode", False 

104 ), 

105 "mysql_query_expansion": kw.pop("with_query_expansion", False), 

106 } 

107 ) 

108 

109 if kw: 

110 raise exc.ArgumentError("unknown arguments: %s" % (", ".join(kw))) 

111 

112 super().__init__(left, against, operators.match_op, modifiers=flags) 

113 

114 @_generative 

115 def in_boolean_mode(self) -> Self: 

116 """Apply the "IN BOOLEAN MODE" modifier to the MATCH expression. 

117 

118 :return: a new :class:`_mysql.match` instance with modifications 

119 applied. 

120 """ 

121 

122 self.modifiers = self.modifiers.union({"mysql_boolean_mode": True}) 

123 return self 

124 

125 @_generative 

126 def in_natural_language_mode(self) -> Self: 

127 """Apply the "IN NATURAL LANGUAGE MODE" modifier to the MATCH 

128 expression. 

129 

130 :return: a new :class:`_mysql.match` instance with modifications 

131 applied. 

132 """ 

133 

134 self.modifiers = self.modifiers.union({"mysql_natural_language": True}) 

135 return self 

136 

137 @_generative 

138 def with_query_expansion(self) -> Self: 

139 """Apply the "WITH QUERY EXPANSION" modifier to the MATCH expression. 

140 

141 :return: a new :class:`_mysql.match` instance with modifications 

142 applied. 

143 """ 

144 

145 self.modifiers = self.modifiers.union({"mysql_query_expansion": True}) 

146 return self