From b39b6023c57b25c00bbed946a83bc44c36d52940 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Wed, 5 Apr 2017 12:55:39 -0400 Subject: Support Postgresql INTERVAL fields spec/reflection Added support for all possible "fields" identifiers when reflecting the Postgresql ``INTERVAL`` datatype, e.g. "YEAR", "MONTH", "DAY TO MINUTE", etc.. In addition, the :class:`.postgresql.INTERVAL` datatype itself now includes a new parameter :paramref:`.postgresql.INTERVAL.fields` where these qualifiers can be specified; the qualifier is also reflected back into the resulting datatype upon reflection / inspection. Change-Id: I33816e68c533b023e0632db6f4e73fefd2de4721 Fixes: #3959 --- lib/sqlalchemy/dialects/postgresql/base.py | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) (limited to 'lib/sqlalchemy/dialects/postgresql/base.py') diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py index 92009450e..802c6a905 100644 --- a/lib/sqlalchemy/dialects/postgresql/base.py +++ b/lib/sqlalchemy/dialects/postgresql/base.py @@ -962,8 +962,19 @@ class INTERVAL(sqltypes.TypeEngine): """ __visit_name__ = 'INTERVAL' - def __init__(self, precision=None): + def __init__(self, precision=None, fields=None): + """Construct an INTERVAL. + + :param precision: optional integer precision value + :param fields: string fields specifier. allows storage of fields + to be limited, such as ``"YEAR"``, ``"MONTH"``, ``"DAY TO HOUR"``, + etc. + + .. versionadded:: 1.2 + + """ self.precision = precision + self.fields = fields @classmethod def _adapt_from_generic_interval(cls, interval): @@ -1301,8 +1312,6 @@ ischema_names = { 'bytea': BYTEA, 'boolean': BOOLEAN, 'interval': INTERVAL, - 'interval year to month': INTERVAL, - 'interval day to second': INTERVAL, 'tsvector': TSVECTOR } @@ -1827,10 +1836,12 @@ class PGTypeCompiler(compiler.GenericTypeCompiler): ) def visit_INTERVAL(self, type_, **kw): + text = "INTERVAL" + if type_.fields is not None: + text += " " + type_.fields if type_.precision is not None: - return "INTERVAL(%d)" % type_.precision - else: - return "INTERVAL" + text += " (%d)" % type_.precision + return text def visit_BIT(self, type_, **kw): if type_.varying: @@ -2489,10 +2500,13 @@ class PGDialect(default.DefaultDialect): args = (int(charlen),) else: args = () - elif attype in ('interval', 'interval year to month', - 'interval day to second'): + elif attype.startswith('interval'): + field_match = re.match(r'interval (.+)', attype, re.I) if charlen: kwargs['precision'] = int(charlen) + if field_match: + kwargs['fields'] = field_match.group(1) + attype = "interval" args = () elif charlen: args = (int(charlen),) -- cgit v1.2.1