Search code examples
pythonsearchflasksqlalchemyflask-sqlalchemy

SQLAlchemy search using .contains() is too sensitive


I have a Flask application that has a search bar where users can search a database for users. This is the code:

users = []
for keyword in query.split():
  result = db.session.query(Users).filter(User.name.contains(keyword)).all()
  for user in result:
    users.append(user.name)

Using the example above, if I was to search for 'a' then every user with the letter 'a' in their name will appear. How can I search the User table so that instead of searching by letter, it would search by word? Thanks.


Solution

  • You can use regular expression with SQLAlchemy:

    result = db.session.query(Users).filter(User.name.op('regexp')(r'\b{}\b'.format(keyword))).all()
    

    \b Matches the empty string, but only at the beginning or end of a word. A word is defined as a sequence of alphanumeric or underscore characters, so the end of a word is indicated by whitespace or a non-alphanumeric, non-underscore character. Note that formally, \b is defined as the boundary between a \w and a \W character (or vice versa), or between \w and the beginning/end of the string, so the precise set of characters deemed to be alphanumeric depends on the values of the UNICODE and LOCALE flags. For example, r'\bfoo\b' matches 'foo', 'foo.', '(foo)', 'bar foo baz' but not 'foobar' or 'foo3'. Inside a character range, \b represents the backspace character, for compatibility with Python’s string literals.

    https://docs.python.org/2/library/re.html