Re: [psycopg] Using infinite values with DateTimeTZRange

Поиск
Список
Период
Сортировка
От Daniele Varrazzo
Тема Re: [psycopg] Using infinite values with DateTimeTZRange
Дата
Msg-id CA+mi_8YfTH0QTqf+abtOprMOoVapS4u32J7GDz0ry9b2EMXYWA@mail.gmail.com
обсуждение исходный текст
Ответ на [psycopg] Using infinite values with DateTimeTZRange  ("Fennell, Felix W." <felnne@bas.ac.uk>)
Ответы Re: [psycopg] Using infinite values with DateTimeTZRange  (Daniele Varrazzo <daniele.varrazzo@gmail.com>)
Re: [psycopg] Using infinite values with DateTimeTZRange  ("Fennell, Felix W." <felnne@bas.ac.uk>)
Список psycopg
On Sun, Aug 20, 2017 at 3:23 PM, Fennell, Felix W. <felnne@bas.ac.uk> wrote:
> Hi,
>
> Apologies if this isn’t the right place to ask questions like this but I am having difficulty storing ‘infinite’
datesusing the DateTimeTZRange object. 

No, it's totally fine, thank you for not having opened a bug in the
bug tracker! :D


> I have a Postgres database with a ‘tstzrange’ column (named validity) and I’d like to store a value in this similar
to‘[“2010-01-01 10:00:00 +01”, infinity]’. 
>
> I’m using SQL Alchemy’s ORM to store data from Python with a model containing:
>
> ```
> from sqlalchemy.dialects.postgresql import TSTZRANGE
> ...
>
> class Principle(Base):
>     __tablename__ = 'principles'
>
>     id = Column(Integer, primary_key=True)
>     validity = Column(TSTZRANGE())
> ```
>
> And then code to generate a timestamp range, using ‘datetime.max()’ to represent infinity as mentioned here [1]:
>
> ```
> from psycopg2.extras import DateTimeTZRange
> ...
>
> from_now = timezone("utc").localize(datetime.now())
> until_forever = timezone("utc").localize(datetime.max)
>
> validity = DateTimeTZRange(from_now, until_forever)
> ```
>
> I then added the code from [2] to translate the use of datetime.max into 'infinity' for use in Postgres, however when
I
> tried to save this model I got this error instead:
>
> 'argument 1 must be datetime.date, not DateTimeTZRange'
>
> I naively tried changing this line:
>
> ```
> psycopg2.extensions.register_adapter(datetime.date, InfDateAdapter)
> ```
>
> to:
>
> ```
> psycopg2.extensions.register_adapter(DateTimeTZRange, InfDateAdapter)
> ```
>
> But that gave me the same error. I'm afraid I don't know Python or this library well enough to adapt the snippet from
> [2] into a form that will work with timestamp ranges - assuming that's what I need to do?
>
> Does anyone here from any advice for how to make this work? I did try googling, but I kept getting directed back to
[2].
>
> Thanks,
> Felix.
>
> [1] http://initd.org/psycopg/docs/extras.html#range-data-types
> [2] http://initd.org/psycopg/docs/usage.html#infinite-dates-handling

You have to adapt what's in [2] to work for datetime objects instead
of dates. Note that python represents with the same class both tz
naive and aware objects: if your program needs to handle both you will
have to perform extra checks in the adapter to dispatch them to the
right postgres type.

    class InfDateTimeTZAdapter:
       min_utc = timezone('utc').localize(datetime.min)
       max_utc = timezone('utc').localize(datetime.max)
       def __init__(self, wrapped):
           self.wrapped = wrapped
       def getquoted(self):
           if self.wrapped == self.max_utc:
               return b"'infinity'::timestamptz"
           elif self.wrapped == self.min_utc:
               return b"'-infinity'::timestamptz"
           else:
                return psycopg2.extensions.DateFromPy(self.wrapped).getquoted()

    psycopg2.extensions.register_adapter(datetime, InfDateTimeTZAdapter)

Once the dt adapter is fixed, the range adapter will use it automatically:

    >>> print psycopg2.extensions.adapt(validity).getquoted()
    tstzrange('2017-08-21T12:59:11.486205+00:00'::date,
'infinity'::datetimetz, '[)')

On the other way around it seems the adapter is already doing what you expect:

    >>> cur.execute("select %s", [validity])
    >>> r = cur.fetchone()[0]
    >>> r.upper == until_forever
    True

but make sure to use psycopg 2.7.2 at least because of bug
<https://github.com/psycopg/psycopg2/issues/536>.

Hope this helps.

-- Daniele


В списке psycopg по дате отправления:

Предыдущее
От: "Fennell, Felix W."
Дата:
Сообщение: [psycopg] Using infinite values with DateTimeTZRange
Следующее
От: Daniele Varrazzo
Дата:
Сообщение: Re: [psycopg] Using infinite values with DateTimeTZRange