views:

32

answers:

1

i have a value that can be integer, float or string, and i create diferent columns:

#declarative
class MyClass(Base):

    #id and other Columns
    _value_str = Column(String(100))
    _value_int = Column(Integer)
    _value_float = Column(Float)

    def __init__(self,...,value):
        self._value_str = value if isinstance(value,(str,unicode)) else None
        self._value_int = value if isinstance(value,int) else None
        self._value_float = value if isinstance(value,float) else None

and i would like to do something like this:

>>> value = 'text'
>>> my_class = MyClass(value, ...)
>>> my_class.value
>>> 'text'
>>> session.add(my_class)
>>> session.commit()
#specialy this
>>> result = session.query(Myclass).filter(Myclass.value == 'text').one()
>>> print result.value 
>>> 'text'

Maybe i have a design problem, i accept any good idea

I'm newbe in SQLAlchemy

Thanks

A: 

Probably a design problem - a bit of a mismatch between your DB and Python. In SQL variables (columns) have a type, whereas in python values have the type.

One possibility would be to use a single column (a string), but pickle the value before you store it.

This can be accomplished automatically with a sqlalchemy custom type.

Something along the lines of the following (uses jsonpickle to do the conversion rather than cpickle):

import sqlalchemy.types as types
import jsonpickle
from copy import deepcopy

class JsonType(types.MutableType, types.TypeDecorator):    
    impl = types.Unicode

    def process_bind_param(self, value, engine):
        return unicode(jsonpickle.encode(value))

    def process_result_value(self, value, engine):
        if value:
            rv = jsonpickle.decode(value)
            return rv
        else:
            return None

    def copy_value(self, value):
        return deepcopy(value)

    def compare_values(self, x, y):
        return x == y

And then use it as follows:

class MyClass(base):
    value = Column(JsonType())
EoghanM
grate!!, i was looking for something like that, but documentations is really bast, thank you
sacabuche
look, could interest you, this is an option ussing MapperExtentionhttp://stackoverflow.com/questions/3020394/sqlalchemy-how-to-map-against-a-read-only-or-calculated-property
sacabuche
Note with this answer that you can't use db functions e.g. sum() on any floats or ints that you store.The docs are actually quite good with SQLAlchemy - they have to cover a lot of ground - but yes, could do with at few more real world examples.
EoghanM