我试图在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对象? 或者有更好的方法吗?
答案 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事件中设置你想要的适配器。