You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					131 lines
				
				3.7 KiB
			
		
		
			
		
	
	
					131 lines
				
				3.7 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								from ... import exc
							 | 
						||
| 
								 | 
							
								from ... import util
							 | 
						||
| 
								 | 
							
								from ...sql import coercions
							 | 
						||
| 
								 | 
							
								from ...sql import elements
							 | 
						||
| 
								 | 
							
								from ...sql import operators
							 | 
						||
| 
								 | 
							
								from ...sql import roles
							 | 
						||
| 
								 | 
							
								from ...sql.base import _generative
							 | 
						||
| 
								 | 
							
								from ...sql.base import Generative
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class match(Generative, elements.BinaryExpression):
							 | 
						||
| 
								 | 
							
								    """Produce a ``MATCH (X, Y) AGAINST ('TEXT')`` clause.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    E.g.::
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        from sqlalchemy import desc
							 | 
						||
| 
								 | 
							
								        from sqlalchemy.dialects.mysql import match
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        match_expr = match(
							 | 
						||
| 
								 | 
							
								            users_table.c.firstname,
							 | 
						||
| 
								 | 
							
								            users_table.c.lastname,
							 | 
						||
| 
								 | 
							
								            against="Firstname Lastname",
							 | 
						||
| 
								 | 
							
								        )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        stmt = (
							 | 
						||
| 
								 | 
							
								            select(users_table)
							 | 
						||
| 
								 | 
							
								            .where(match_expr.in_boolean_mode())
							 | 
						||
| 
								 | 
							
								            .order_by(desc(match_expr))
							 | 
						||
| 
								 | 
							
								        )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Would produce SQL resembling::
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        SELECT id, firstname, lastname
							 | 
						||
| 
								 | 
							
								        FROM user
							 | 
						||
| 
								 | 
							
								        WHERE MATCH(firstname, lastname) AGAINST (:param_1 IN BOOLEAN MODE)
							 | 
						||
| 
								 | 
							
								        ORDER BY MATCH(firstname, lastname) AGAINST (:param_2) DESC
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    The :func:`_mysql.match` function is a standalone version of the
							 | 
						||
| 
								 | 
							
								    :meth:`_sql.ColumnElement.match` method available on all
							 | 
						||
| 
								 | 
							
								    SQL expressions, as when :meth:`_expression.ColumnElement.match` is
							 | 
						||
| 
								 | 
							
								    used, but allows to pass multiple columns
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    :param cols: column expressions to match against
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    :param against: expression to be compared towards
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    :param in_boolean_mode: boolean, set "boolean mode" to true
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    :param in_natural_language_mode: boolean , set "natural language" to true
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    :param with_query_expansion: boolean, set "query expansion" to true
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    .. versionadded:: 1.4.19
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    .. seealso::
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        :meth:`_expression.ColumnElement.match`
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    """
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    __visit_name__ = "mysql_match"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    inherit_cache = True
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def __init__(self, *cols, **kw):
							 | 
						||
| 
								 | 
							
								        if not cols:
							 | 
						||
| 
								 | 
							
								            raise exc.ArgumentError("columns are required")
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        against = kw.pop("against", None)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if against is None:
							 | 
						||
| 
								 | 
							
								            raise exc.ArgumentError("against is required")
							 | 
						||
| 
								 | 
							
								        against = coercions.expect(
							 | 
						||
| 
								 | 
							
								            roles.ExpressionElementRole,
							 | 
						||
| 
								 | 
							
								            against,
							 | 
						||
| 
								 | 
							
								        )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        left = elements.BooleanClauseList._construct_raw(
							 | 
						||
| 
								 | 
							
								            operators.comma_op,
							 | 
						||
| 
								 | 
							
								            clauses=cols,
							 | 
						||
| 
								 | 
							
								        )
							 | 
						||
| 
								 | 
							
								        left.group = False
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        flags = util.immutabledict(
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                "mysql_boolean_mode": kw.pop("in_boolean_mode", False),
							 | 
						||
| 
								 | 
							
								                "mysql_natural_language": kw.pop(
							 | 
						||
| 
								 | 
							
								                    "in_natural_language_mode", False
							 | 
						||
| 
								 | 
							
								                ),
							 | 
						||
| 
								 | 
							
								                "mysql_query_expansion": kw.pop("with_query_expansion", False),
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if kw:
							 | 
						||
| 
								 | 
							
								            raise exc.ArgumentError("unknown arguments: %s" % (", ".join(kw)))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        super(match, self).__init__(
							 | 
						||
| 
								 | 
							
								            left, against, operators.match_op, modifiers=flags
							 | 
						||
| 
								 | 
							
								        )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @_generative
							 | 
						||
| 
								 | 
							
								    def in_boolean_mode(self):
							 | 
						||
| 
								 | 
							
								        """Apply the "IN BOOLEAN MODE" modifier to the MATCH expression.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        :return: a new :class:`_mysql.match` instance with modifications
							 | 
						||
| 
								 | 
							
								         applied.
							 | 
						||
| 
								 | 
							
								        """
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        self.modifiers = self.modifiers.union({"mysql_boolean_mode": True})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @_generative
							 | 
						||
| 
								 | 
							
								    def in_natural_language_mode(self):
							 | 
						||
| 
								 | 
							
								        """Apply the "IN NATURAL LANGUAGE MODE" modifier to the MATCH
							 | 
						||
| 
								 | 
							
								        expression.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        :return: a new :class:`_mysql.match` instance with modifications
							 | 
						||
| 
								 | 
							
								         applied.
							 | 
						||
| 
								 | 
							
								        """
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        self.modifiers = self.modifiers.union({"mysql_natural_language": True})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @_generative
							 | 
						||
| 
								 | 
							
								    def with_query_expansion(self):
							 | 
						||
| 
								 | 
							
								        """Apply the "WITH QUERY EXPANSION" modifier to the MATCH expression.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        :return: a new :class:`_mysql.match` instance with modifications
							 | 
						||
| 
								 | 
							
								         applied.
							 | 
						||
| 
								 | 
							
								        """
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        self.modifiers = self.modifiers.union({"mysql_query_expansion": True})
							 |