Full text support in peewee

Adds support for full text search in peewee with the creation of two new field types: `FullIndexedCharField` and `FullIndexedTextField`.

Note that this change depends upon https://github.com/zzzeek/sqlalchemy/pull/339

[Delivers #137453279]
[Delivers #137453317]
This commit is contained in:
Joseph Schorr 2017-01-11 14:52:12 -05:00
parent 048f932094
commit d89c79b92d
4 changed files with 105 additions and 2 deletions

38
data/text.py Normal file
View file

@ -0,0 +1,38 @@
from peewee import Clause, SQL, fn, TextField, Field
def _escape_wildcard(search_query):
""" Escapes the wildcards found in the given search query so that they are treated as *characters*
rather than wildcards when passed to a LIKE or ILIKE clause with an ESCAPE '!'.
"""
search_query = (search_query
.replace('!', '!!')
.replace('%', '!%')
.replace('_', '!_')
.replace('[', '!['))
return search_query
def prefix_search(field, prefix_query):
""" Returns the wildcard match for searching for the given prefix query. """
# Escape the known wildcard characters.
prefix_query = _escape_wildcard(prefix_query)
return Field.__pow__(field, Clause(prefix_query + '%', SQL("ESCAPE '!'")))
def match_mysql(field, search_query):
""" Generates a full-text match query using a Match operation, which is needed for MySQL.
"""
if field.name.find('`') >= 0: # Just to be safe.
raise Exception("How did field name '%s' end up containing a backtick?" % field.name)
return Clause(fn.MATCH(SQL("`%s`" % field.name)), fn.AGAINST(SQL('%s', search_query)),
parens=True)
def match_like(field, search_query):
""" Generates a full-text match query using an ILIKE operation, which is needed for SQLite and
Postgres.
"""
escaped_query = _escape_wildcard(search_query)
clause = Clause('%' + escaped_query + '%', SQL("ESCAPE '!'"))
return Field.__pow__(field, clause)