SQLAlchemy 在原生 SQL 表达式中重写 types.DateTime
在使用SQLAlchemy和原始SQL表达式时,是否可以改变默认的type.DateTime行为呢?
比如,当我使用下面这段代码:
myconnection.execute(text("select * from mytable where mydate > :mydate), {'mydate': mypythondatetimeobject)}
我希望type.DateTime能够自动去掉日期时间对象中的时区信息。
更新:我发现通过在查询中使用bindparam和Typedecorator可以做到这一点,像这样:
class MyType(types.TypeDecorator):
impl = types.DateTime
def process_bind_param(self, value, dialect):
if value is not None:
return value.replace(tzinfo=None)
session.execute(
text(myquery, bindparams=[bindparam('mydateparam',
type_=MyType())]),
{'mydateparam':mydate}
)
但是我真的不想在每个查询中都使用“bindparams”。难道没有办法简单地替换或覆盖默认的types.DateTime行为吗?
1 个回答
1
如果你使用的是基于表格元数据的SQL表达式,那么你只需要在合适的列上设置你的MyType。直接用文本的方式就没那么方便了。不过,你可以把你的MyType放到sqlalchemy.types.type_map里,跟datetime类关联起来,不过现在这个方法还不是公开的API。
如果是我,我会这样做:
def mytext(stmt, params):
bindparams = []
for k, v in params:
if isinstance(v, datetime):
type_ = MyType()
else:
type_ = None
bindparams.append(bindparam(k, v, type_=type))
return text(stmt, bindparams=bindparams)
然后就可以用mytext("select * from table where date=:date", {'date':datetime.today()})来查询了。