SQLAlchemy TypeDecorator不起作用

时间:2018-04-04 13:46:25

标签: python sqlalchemy

我正在尝试向ORM类成员添加自定义方法,以使其处理与此成员相关的内容。试图关注documentation

class EnhDateTime(types.TypeDecorator):
    impl = types.DateTime
    def foo(self):
        return "foo"

class MyDoc(Base):
     id = Column(Integer, primary_key=True,  autoincrement=False) 
     created = Column(EnhDateTime)

doc = session.query(MyDoc).filter_by(id=123).one()

不幸的是没有发生任何事情,该成员仍然是DateTime类型:

type(doc.created)
  

datetime.datetime

doc.created.foo()
  

AttributeError的

1 个答案:

答案 0 :(得分:2)

TypeDecorator不是它只是装饰类型的类型,即它定义了在某些情况下调用的某些方法,例如在向数据库传递值或从数据库传递值时。您需要实现两种方法process_bind_param()process_result_value()。在那里,您可以将数据库中的值转换为/您想要的任何值。

例如,请参阅TypeDecorator recipes section

中的JSON示例
from sqlalchemy.types import TypeDecorator, VARCHAR
import json

class JSONEncodedDict(TypeDecorator):

    impl = VARCHAR

    def process_bind_param(self, value, dialect):
        if value is not None:
            value = json.dumps(value)

        return value

    def process_result_value(self, value, dialect):
        if value is not None:
            value = json.loads(value)
        return value

示例:

from datetime import datetime
from sqlalchemy.types import TypeDecorator, DATETIME

class _EnhDateTime(datetime):

    def foo(self):
        return 'foo'


class EnhDateTime(TypeDecorator):

    impl = DATETIME

    def process_result_value(self, value, dialect):
        if value is not None:
            value = _EnhDateTime(
                value.year, value.month, value.day, value.hour, value.minute,
                value.second, value.microsecond, value.tzinfo
            )
        return value

我们不需要实施process_bind_param(),因为_EnhDateTime个实例 datetime个实例,因此DATETIME的默认绑定处理器应该这样做。