Hello everyone!

I have created a little module that generates a sqlalchemy query from
an string (yeah, I needed some help:
http://groups.google.com/group/sqlalchemy/browse_thread/thread/6ea3241b1c653444
)

At certain point, I check the type of the field I'm filtering
by creating an instance of the class I'm querying, getting the
contents of said field and checking its type.

I create the instance with cls() (instantiate the class without
passing any parameter to the constructor). That works fine... as long
as I don't need to pass any parameter to the constructor... otherwise,
I would get:
TypeError: __init__() takes exactly [whatever] arguments (1 given).

The field I want to check is a synonym in the class "level". I'd like
to know if there's a way to get the Python type (int, list...) from
that synonym (without needed to create an instance of the class)

Let me explain with an example.

Let's say I have a class "Product":

-------------------- Product.py ------------------
class Product(declarativeBase):
        __tablename__ = "products"

        _id = Column("id", Integer, primary_key=True)
        _model = Column("model", String(30))
        _number = Column("category", Integer)

        def __init__(self):
                self.model = ""
                self.number = 0

        def setId(self, id):
                self._id = int(id)

        def getId(self):
                return self._id

        def setModel(self, model):
                self._model = model

        def getModel(self):
                return self._model

        # [...] more code, more getters, setters [...]

        id = sqlalchemy.orm.synonym('_id', descriptor=property(getId, setId))
        model = sqlalchemy.orm.synonym('_model',
                                        descriptor=property(getModel, setModel))
        number = sqlalchemy.orm.synonym('_number',
                                        descriptor=property(getNumber, 
setNumber))

-------------------------------------

The user can input a query as:
"Product.model=='foo' && Product.number=='5'"
(number may be an string -quoted, I mean- here)

The idea is that then I can pass that string and the class I want to
get results for to my QueryTokenizer class:
    queryTokenizer = QueryTokenizer(queryString, classToQuery)
# class to query is the class "object": Product.Product, which is what
# if I do prod = Product.Product() would store in "prod" an instance of
# the "Product" class

So a call to queryTokenizer.getQuery() would return, for the query
string detailed above:

sqlalchemy.and_( Product.Product.model.__eq__("foo"),
                           Product.Product.number__eq__(5))

with number being properly casted to an int()

So I can put that in a method (getByCustomFilter, to call it somehow) and do:

from mylibs.product import Product
# ...
queryTokenizer = QueryTokenizer(queryString, Product.Product)
retval = 
Database.session.query(Product.Product).filter(queryTokenizer.getQuery()).all()


The problem is that, in order to perform that cast, I need to find out
the type of the field I'm filtering for (I need to know that in the
instances of Product, "Product.number" is an int).
To achieve that, I do the following:
I instantiate the class, get the "number" field of the *instance*,
check its type (will be int) and cast accordingly (cast '5' to int).
Something like:

------- QueryTokenizer-----------
# [ . . .]
def clean(self, classToQuery):
        instance_of_class = classToQuery() # In the example, this the same as 
doing:
                                                        #  instance_of_class 
=Product.Product()
        type_in_instances = type(getattr(instance_of_class, "number"))#Gives 
type 'int'
        castedValue = type_in_instances(value_to_check) #From the string "5"
                                                                                
 # gives the int 5
# [ . . .]

---------------------------

But of course, that only works if the constructor of "classToQuery"
doesn't require arguments. Otherwise the call classToQuery() gives a
type error.

I would like to know if I can get that "int" from the class itself
(not from an instance). In the class, if I do (getattr(classToQuery,
"number")) I get a sqlalchemy.orm.synonym. I would like to know if
from that I can somehow get <type 'int'> (what I get when in python I
do type(5), type(0)... )

This is not only done so the user can input "number == '5'" (I could
force the user to input number==5) but also as a layer of security to
make sure the query is correct and that no "weird/insecure" stuff is
going on.

Thank you!

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