From: Mike Bayer Date: Sun, 1 Nov 2009 22:47:14 +0000 (+0000) Subject: - INTERVAL supports an optional "precision" argument X-Git-Tag: rel_0_6beta1~202 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e8854fe945e94d0fe654e83397c47f8b0fb1f1e8;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - INTERVAL supports an optional "precision" argument corresponding to the argument that PG accepts. - Added support for reflecting the INTERVAL YEAR TO MONTH and INTERVAL DAY TO SECOND syntaxes of the INTERVAL type. [ticket:460] --- diff --git a/CHANGES b/CHANGES index 403b7fa59f..1a4c7e1cae 100644 --- a/CHANGES +++ b/CHANGES @@ -452,7 +452,10 @@ CHANGES to issue the appropriate CREATE TYPE/DROP TYPE commands as needed, supports unicode labels, supports reflection. [ticket:1511] - + + - INTERVAL supports an optional "precision" argument + corresponding to the argument that PG accepts. + - using new dialect.initialize() feature to set up version-dependent behavior. @@ -674,6 +677,10 @@ CHANGES This is postgresql.DOUBLE_PRECISION in 0.6. [ticket:1085] + - Added support for reflecting the INTERVAL YEAR TO MONTH + and INTERVAL DAY TO SECOND syntaxes of the INTERVAL + type. [ticket:460] + - Corrected the "has_sequence" query to take current schema, or explicit sequence-stated schema, into account. [ticket:1576] diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py index 9570dae57c..c41d5b359e 100644 --- a/lib/sqlalchemy/dialects/postgresql/base.py +++ b/lib/sqlalchemy/dialects/postgresql/base.py @@ -105,6 +105,12 @@ PGMacAddr = MACADDR class INTERVAL(sqltypes.TypeEngine): __visit_name__ = 'INTERVAL' + def __init__(self, precision=None): + self.precision = precision + + def adapt(self, impltype): + return impltype(self.precision) + PGInterval = INTERVAL class BIT(sqltypes.TypeEngine): @@ -238,6 +244,8 @@ ischema_names = { 'bytea' : BYTEA, 'boolean' : BOOLEAN, 'interval':INTERVAL, + 'interval year to month':INTERVAL, + 'interval day to second':INTERVAL, } @@ -426,7 +434,10 @@ class PGTypeCompiler(compiler.GenericTypeCompiler): return "TIME " + (type_.timezone and "WITH" or "WITHOUT") + " TIME ZONE" def visit_INTERVAL(self, type_): - return "INTERVAL" + if type_.precision is not None: + return "INTERVAL(%d)" % type_.precision + else: + return "INTERVAL" def visit_BIT(self, type_): return "BIT" @@ -839,10 +850,10 @@ class PGDialect(default.DefaultDialect): else: numericprec, numericscale = charlen.split(',') charlen = False - if attype == 'double precision': + elif attype == 'double precision': numericprec, numericscale = (53, False) charlen = False - if attype == 'integer': + elif attype == 'integer': numericprec, numericscale = (32, 0) charlen = False args = [] diff --git a/lib/sqlalchemy/test/testing.py b/lib/sqlalchemy/test/testing.py index 654153adba..369aa3a6fc 100644 --- a/lib/sqlalchemy/test/testing.py +++ b/lib/sqlalchemy/test/testing.py @@ -639,7 +639,8 @@ class ComparesTables(object): eq_(c.nullable, reflected_c.nullable) if strict_types: - assert type(reflected_c.type) is type(c.type), "Type '%s' doesn't correspond to type '%s'" % (reflected_c.type, c.type) + assert type(reflected_c.type) is type(c.type), \ + "Type '%s' doesn't correspond to type '%s'" % (reflected_c.type, c.type) else: self.assert_types_base(reflected_c, c) diff --git a/test/dialect/test_postgresql.py b/test/dialect/test_postgresql.py index e4a5ffa558..aa2b99275a 100644 --- a/test/dialect/test_postgresql.py +++ b/test/dialect/test_postgresql.py @@ -4,7 +4,7 @@ from sqlalchemy.test import engines import datetime from sqlalchemy import * from sqlalchemy.orm import * -from sqlalchemy import exc, schema +from sqlalchemy import exc, schema, types from sqlalchemy.dialects.postgresql import base as postgresql from sqlalchemy.engine.strategies import MockEngineStrategy from sqlalchemy.test import * @@ -1320,17 +1320,35 @@ class SpecialTypesTest(TestBase, ComparesTables): global metadata, table metadata = MetaData(testing.db) + # create these types so that we can issue + # special SQL92 INTERVAL syntax + class y2m(types.UserDefinedType, postgresql.INTERVAL): + def get_col_spec(self): + return "INTERVAL YEAR TO MONTH" + + class d2s(types.UserDefinedType, postgresql.INTERVAL): + def get_col_spec(self): + return "INTERVAL DAY TO SECOND" + table = Table('sometable', metadata, Column('id', postgresql.PGUuid, primary_key=True), Column('flag', postgresql.PGBit), Column('addr', postgresql.PGInet), Column('addr2', postgresql.PGMacAddr), Column('addr3', postgresql.PGCidr), - Column('doubleprec', postgresql.DOUBLE_PRECISION) - + Column('doubleprec', postgresql.DOUBLE_PRECISION), + Column('plain_interval', postgresql.INTERVAL), + Column('year_interval', y2m()), + Column('month_interval', d2s()), + Column('precision_interval', postgresql.INTERVAL(precision=3)) ) metadata.create_all() + + # cheat so that the "strict type check" + # works + table.c.year_interval.type = postgresql.INTERVAL() + table.c.month_interval.type = postgresql.INTERVAL() @classmethod def teardown_class(cls): @@ -1341,7 +1359,8 @@ class SpecialTypesTest(TestBase, ComparesTables): t = Table('sometable', m, autoload=True) self.assert_tables_equal(table, t, strict_types=True) - + assert t.c.plain_interval.type.precision is None + assert t.c.precision_interval.type.precision == 3 class MatchTest(TestBase, AssertsCompiledSQL): __only_on__ = 'postgresql'