一个字段不同数据类型 [SQLAlchemy]

1 投票
1 回答
1655 浏览
提问于 2025-04-16 00:44

我有一个值,它可以是整数、浮点数或者字符串,我为它创建了不同的列:

#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

我想做类似这样的事情:

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

也许我在设计上有问题,欢迎任何好的建议

我在SQLAlchemy方面还是个新手

谢谢

1 个回答

4

这可能是个设计上的问题——你的数据库和Python之间有点不匹配。在SQL中,变量(也就是列)是有类型的,而在Python中,值才有类型。

一种解决办法是使用一个单独的列(用字符串来存储),但在存储之前先把值进行序列化处理。

这可以通过一个叫做sqlalchemy自定义类型的功能自动完成。

可以参考下面的代码(使用jsonpickle来进行转换,而不是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

然后可以这样使用:

class MyClass(base):
    value = Column(JsonType())

撰写回答