views:

31

answers:

1

is it possible to override the default type.DateTime behaviour when using sqlalchemy with raw sql expressions?

for example when using

myconnection.execute(text("select * from mytable where mydate > :mydate), {'mydate': mypythondatetimeobject)}

, i would like to have type.DateTime to automatically strip the TimeZone from the DateTime object.

UPDATE: i found out, that it works by using bindparam and a Typedecorator on the query like this:

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}
)

but i really dont want to use "bindparams" on every query. isnt it possible to simply replace or override the default types.DateTime behaviour somehow?

+1  A: 

If you used SQL expressions based on Table metadata, then you'd just set your MyType on the appropriate columns. The plain text approach loses some convenience. You could stick your MyType into the sqlalchemy.types.type_map keyed to the datetime class, though this is currently not public API.

If it were me I'd do:

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)

then just use mytext("select * from table where date=:date", {'date':datetime.today()})

zzzeek
thank you! i am now using your "mytext" solution, slightly adapted.
return1.at