Hi,

I think I've encountered my first time caring about psycopg2 mangling 
intervals and this looks super helpful. I was wondering if you have any 
updated suggestions since this post is a few years old?

Thanks!
David

On Tuesday, December 24, 2013 at 6:27:06 PM UTC-5, David Bolen wrote:
>
> Sibylle Koczian <nulla....@web.de <javascript:>> writes: 
>
> > Exactly, that's it. The stackoverflow discussion was very instructive, 
> > thank you! I'll try out psycopg2-dateutils. 
>
> I'm a big fan of dateutil.  If you do use it, you may also choose to 
> bypass the use of timedelta entirely, since as you've seen it can fail 
> to accurately represent the database value (timedelta only has days, 
> minutes and seconds as components). 
>
> For example, I use the code below to map PostgreSQL interval columns 
> directly to dateutil's relativedelta subclass. 
>
> Any returned queries involving interval values will use the new 
> Interval type automatically, and will accurately round-trip.  You'll 
> have to use the Interval class explicitly when creating values to go 
> the other way. 
>
> The mapping occurs purely at the psycopg2 level. 
>
> -- David 
>
>
> # 
> # 
> -------------------------------------------------------------------------- 
> #  Interval Mapping 
> # 
> #  Override normal psycopg2 mapping so Interval types get mapped into a 
> #  relativedelta since it can more accurately represent them.  We use our 
> own 
> #  relativedelta subclass as we need it to be a new style class for 
> psycopg2 
> #  adaptation to work.  Other code must use our Interval class if trying 
> to 
> #  store such data back into the database. 
> # 
> #  In this case there's nothing to do at the SQLAlchemy layer because for 
> #  PostgreSQL, it just uses the data as provided by psycopg2. 
> # 
> -------------------------------------------------------------------------- 
> # 
>
> class Interval(relativedelta, object): 
>     pass 
>
> import psycopg2 
> from psycopg2._psycopg import INTERVAL as psycopg2_INTERVAL 
> from psycopg2.extensions import new_type, register_type, register_adapter, 
> AsIs 
> import re 
>
> interval_re = re.compile(' *' 
>                          '((?P<years>\d+) y\D*)?' 
>                          '((?P<months>\d+) m\D*)?' 
>                          '((?P<days>\d+) d\D*)?' 
>                         
>  '((?P<hours>\d+):(?P<minutes>\d+):(?P<seconds>\d+))?' 
>                          '(\.(?P<subseconds>\d+))?$') 
>
>
> # Configure handling for supplying an Interval to store in the database 
>
> def adapt_interval(interval): 
>     adapter = AsIs("'%d years %d months %d days %02d:%02d:%02d.%06d'" % 
>                    (interval.years, interval.months, interval.days, 
>                     interval.hours, interval.minutes, interval.seconds, 
>                     interval.microseconds)) 
>     return adapter 
>
> register_adapter(Interval, adapt_interval) 
>         
> # Configure handling upon receiving an Interval from the database 
>
> def cast_interval(value, cur): 
>     if value is None: 
>         return None 
>
>     m = interval_re.match(value) 
>     if m: 
>         vals = m.groupdict(0) 
>         # Most everything is direct, but subseconds has a varying 
> precision, 
>         # so force it to be microseconds if we had a value 
>         microseconds = vals['subseconds'] 
>         if microseconds: 
>             microseconds = (microseconds + '000000')[:6] 
>         return Interval(years=int(vals['years']), 
>                         months=int(vals['months']), 
>                         days=int(vals['days']), 
>                         hours=int(vals['hours']), 
>                         minutes=int(vals['minutes']), 
>                         seconds=int(vals['seconds']), 
>                         microseconds=int(microseconds)) 
>     
>     else: 
>         raise InterfaceError("Bad interval representation: %r" % value) 
>
> INTERVAL = new_type(psycopg2_INTERVAL.values, "INTERVAL", cast_interval) 
> register_type(INTERVAL) 
>
>
>

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/9657cb0a-83f0-4253-95dd-6d07186d0aa0o%40googlegroups.com.

Reply via email to