Hello list...

I would like to allow the users to perform certain queries without me
(or well... my server) knowing in advance what those queries are going
to be (without hard-coding the query).

For instance: I have a “Product” class. One of it's fields is
"manufacturer" and another is "model"

class Product(declarativeBase):
       def __init__(self):
               self.model = ""
               self.manufacturer = ""

I would like the user be able to input an string with a query, such as
“Product.model != 'foo' or Product.model != 'bar'”
or:
"Product.model == 'foo' && Product.manufacturer == 'bar'"

I have created a little Python module (queryTree) that tokenizes the
string and generates a tree for that kind of queries. For the last one
mentioned above, it would be something like:


                  sqlalchemy.and_
            /                        \
         ==                            ==
  /             \             /               \
Product.model   "foo"  Product.manufacturer   "bar"

1) The “&&” string can be converted to (stored as) the sqlalchemy.and_ method
2) The fields of Product are sqlalchemy.orm.synonym(s). If I pass my
tree module the class I'm going to perform the query for, it can call
getattr(cls, "model") and get the synonym (I mean: get the
Product.model synonym itself instead of the “model” string)
3) Equally, the comparators are get with getattr(Product, "__eq__") or
getattr(Product, "__ne__") so I can store in the tree node the
comparator function instead of the string “==” or “!=”

But when I try to run the query:
from mylibs.product import Product
queryString = "Product.model == 'foo' && Product.manufacturer == 'bar'"
session.query(Product.Product).filter(queryTree.getQuery(queryString,
Product.Product))

I get an exception:
  File "/home/hbr/Documents/my-cms/backlib/product/ProductManager.py",
line 62, in getByCustomFilter
    retval = 
Database.session.query(Product.Product).filter(queryTokenizer.getQuery()).all()
  File "<string>", line 1, in <lambda>
  File 
"/home/hbr/.buildout/eggs/SQLAlchemy-0.6.5-py2.6.egg/sqlalchemy/orm/query.py",
line 52, in generate
    fn(self, *args[1:], **kw)
  File 
"/home/hbr/.buildout/eggs/SQLAlchemy-0.6.5-py2.6.egg/sqlalchemy/orm/query.py",
line 942, in filter
    "filter() argument must be of type "
ArgumentError: filter() argument must be of type
sqlalchemy.sql.ClauseElement or string


I could easily modify my query generator module to get the query string...:
“and_(Product.model == 'foo', Product.manufacturer == 'bar')” so a
call to eval(“and_(Product.model == 'foo', Product.manufacturer ==
'bar')”) would probably work, but I'd like to avoid the use of eval
because of the security issues it usually implies.

With some other tests, I've got some other exceptions that made me
realize that I could possibly modify somehow the nodes of my tree
until getting "something" that is accepted by MySQL as a valid query,
but that's kind of cheating... I'd like to use pure SqlAlchemy if
possible (I trust SqlAlchemy more than my programming skills) :-D

Thank you in advance. Every hint will be deeply appreciated.

-- 
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