Greetings,

I have been using SQLA for a few months.

For admin CRUD index pages I have been using a naive search_keywords 
function as
seen at end of message.

Instead of using a primitive shlex.split, which incidentally is not unicode
friendly, and one crude search_type (AND|OR) I'd like to use something 
that will
lex/parse a search string and build the queries.

eg.
  ((x or z or y) and q) or not "h m"
 
I imagine this would be a fairly common requirement however I can't seem 
to find
any implementation anywhere.

I used google code search with the query "pyparsing sqlalchemy lang:python"
however found no useful results.

Before I set off attempting to learn about lexing/[py]parsing I was 
wondering if
any one has some code like this laying about underneath their bed.

Cheers.

================================================================================
=                                                                              
=
================================================================================

ensure_list = lambda l: l if isinstance(l, list) else [l]

def shlex_split(line):
    """ shlex.split does not handle unicode properly so must be codecd """
    if isinstance(line, unicode):
        line = line.encode('utf-8')
    return [ w.strip().decode('utf-8') for w in shlex.split(line) ]

def like_escape(s):
    return ( s.replace('\\', '\\\\')
              .replace('%', '\\%')
              .replace('_', '\\_') )

def search_keywords(q, model, key_words='', fields=[], search_type='and',
                    default_fields=[], **kw):
   
    if not key_words:
        return q
   
    # Escape the search string
    # TODO: this should be done by formencode validators
    if isinstance(key_words, basestring):
        key_words =  shlex_split(key_words)

    # Space delimited keyword search
    key_words = ['%'+ like_escape(w) +'%' for w in key_words]

    # Make sure fields is a list and if none specified use default
    fields = ensure_list(fields) if fields else default_fields  # TODO

    # WHERE ($X OR $Y) AND|OR ($Z OR $Q) ...
    search_type = and_ if search_type == 'and' else or_

    if key_words:
        q = q.filter (
            search_type ( * (
                or_(  *( getattr(model, field).like(key_word, escape=r'\\')
                         for field in fields ) )
                    for key_word in key_words
                )               
            )
        )

    return q
   
================================================================================
=                                                                              
=
================================================================================

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to