SQLAlchemy中dateutil.relativedelta支持的子类Interval

时间:2013-10-10 11:22:57

标签: python postgresql sqlalchemy

我试图在sqlalchemy中实现对相对日期范围(月,年)的基本支持。使用postgres作为数据库我认为继承sqlalchemy.dialects.postgres.Interval并将返回的python类型更改为dateutil.relativedelta.relativedelta将是最好/最快的方式。

from sqlalchemy import types
from sqlalchemy.dialects.postgres import INTERVAL
from dateutil import relativedelta

class DateInterval(INTERVAL):
    def result_processor(self, dialect, coltype):
        def process(value):
            return value
        return process

@property
def python_type(self):
    return relativedelta.relativedelta


class MyInterval(types.TypeDecorator):
    impl = DateInterval

    def process_bind_param(self, value, dialect):
        result = ''
        for attr in ["years", "months", "days", "hours", "minutes", "seconds"]:
            tempvalue = getattr(value, attr)
            if tempvalue:
                result += "%s %s " % (tempvalue, attr)
        return result

    def process_result_value(self, value, engine):
        return value

    @property
    def python_type(self):
        return relativedelta.relativedelta

刷新到数据库按预期工作,process_bind_param方法有效。 之后取出它,不会。 result_processor方法的process函数中的value参数已经是timedelta对象。在哪里挂钩,将原始值处理为relativedelta对象? 或者有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

psycopg2正在返回那些timedeltas。如果你想拦截那些,你需要在psycopg2级别增加一些东西:http://initd.org/psycopg/docs/advanced.html#type-casting-of-sql-types-into-python-objects也许你可以使用new_type()绕过psycopg2的INTERVAL对象的默认类型转换器。

第一步是从普通的psycopg2连接/光标返回原始值,以确保您在该级别拥有控制权。

然后当你弄清楚如何获得它时,你可以拦截新创建的psycopg2连接对象,并在connect事件中设置你想要的适配器。