From 9f4b5b37a3e1a938f40e53aae28cdf7853decad8 Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Tue, 18 Jun 2013 15:00:30 +0100 Subject: [PATCH] Added doc example to convert date.max to infinity See issue #163. --- doc/src/extras.rst | 11 +++++++++++ doc/src/usage.rst | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/doc/src/extras.rst b/doc/src/extras.rst index 08767599..66369abd 100644 --- a/doc/src/extras.rst +++ b/doc/src/extras.rst @@ -453,6 +453,17 @@ automatically casted into instances of these classes. .. autoclass:: DateTimeRange .. autoclass:: DateTimeTZRange +.. note:: + + Python lacks a representation for :sql:`infinity` date so Psycopg converts + the value to `date.max` and such. When written into the database these + dates will assume their literal value (e.g. :sql:`9999-12-31` instead of + :sql:`infinity`). Check :ref:`infinite-dates-handling` for an example of + an alternative adapter to map `date.max` to :sql:`infinity`. An + alternative dates adapter will be used automatically by the `DateRange` + adapter and so on. + + Custom |range| types (created with |CREATE TYPE|_ :sql:`... AS RANGE`) can be adapted to a custom `Range` subclass: diff --git a/doc/src/usage.rst b/doc/src/usage.rst index 3321981b..f7ffd691 100644 --- a/doc/src/usage.rst +++ b/doc/src/usage.rst @@ -496,6 +496,7 @@ the same way:: .. seealso:: `PostgreSQL date/time types `__ + .. index:: single: Time Zones @@ -530,6 +531,40 @@ rounded to the nearest minute, with an error of up to 30 seconds. versions use `psycopg2.extras.register_tstz_w_secs()`. +.. index:: + double: Date Objects, Infinite + +.. _infinite-dates-handling: + +Infinite dates handling +''''''''''''''''''''''' + +PostgreSQL can store the representation of an "infinite" date, timestamp, or +interval. Infinite dates are not available to Python, so these objects are +mapped to `!date.max`, `!datetime.max`, `!interval.max`. Unfortunately the +mapping cannot be bidirectional so these dates will be stored back into the +database with their values, such as :sql:`9999-12-31`. + +It is possible to create an alternative adapter for dates and other objects +to map `date.max` to :sql:`infinity`, for instance:: + + class InfDateAdapter: + def __init__(self, wrapped): + self.wrapped = wrapped + def getquoted(self): + if self.wrapped == datetime.date.max: + return "'infinity'::date" + elif self.wrapped == datetime.date.min: + return "'-infinity'::date" + else: + return psycopg2.extensions.DateFromPy(self.wrapped).getquoted() + + psycopg2.extensions.register_adapter(datetime.date, InfDateAdapter) + +Of course it will not be possible to write the value of `date.max` in the +database anymore: :sql:`infinity` will be stored instead. + + .. _adapt-list: Lists adaptation