diff options
author | Chris Withers <chris@simplistix.co.uk> | 2013-05-19 08:50:06 +0100 |
---|---|---|
committer | Chris Withers <chris@simplistix.co.uk> | 2013-06-10 12:09:55 +0100 |
commit | 70edfa229c8bd3d34f11fbfeaf5a7fa6bb1dfff2 (patch) | |
tree | ef228e6d943875af55865fabb6b11e00830bcda5 /test/dialect/test_postgresql.py | |
parent | 1652491cc6ef44c803e58c0d842818ab7310f498 (diff) | |
download | sqlalchemy-70edfa229c8bd3d34f11fbfeaf5a7fa6bb1dfff2.tar.gz |
Basic type support for the new range types in postgres 9.2
Diffstat (limited to 'test/dialect/test_postgresql.py')
-rw-r--r-- | test/dialect/test_postgresql.py | 124 |
1 files changed, 123 insertions, 1 deletions
diff --git a/test/dialect/test_postgresql.py b/test/dialect/test_postgresql.py index 00e5c07ab..de37ffd7d 100644 --- a/test/dialect/test_postgresql.py +++ b/test/dialect/test_postgresql.py @@ -17,7 +17,8 @@ from sqlalchemy import Table, Column, select, MetaData, text, Integer, \ from sqlalchemy.orm import Session, mapper, aliased from sqlalchemy import exc, schema, types from sqlalchemy.dialects.postgresql import base as postgresql -from sqlalchemy.dialects.postgresql import HSTORE, hstore, array +from sqlalchemy.dialects.postgresql import HSTORE, hstore, array, \ + INT4RANGE, INT8RANGE, NUMRANGE, DATERANGE, TSRANGE, TSTZRANGE import decimal from sqlalchemy import util from sqlalchemy.testing.util import round_decimal @@ -3232,3 +3233,124 @@ class HStoreRoundTripTest(fixtures.TablesTest): def test_unicode_round_trip_native(self): engine = testing.db self._test_unicode_round_trip(engine) + +class _RangeTypeMixin(object): + __requires__ = 'range_types', + __dialect__ = 'postgresql+psycopg2' + + @property + def extras(self): + # done this way so we don't get ImportErrors with + # older psycopg2 versions. + from psycopg2 import extras + return extras + + @classmethod + def define_tables(cls, metadata): + # no reason ranges shouldn't be primary keys, + # so lets just use them as such + Table('data_table', metadata, + Column('range', cls._col_type, primary_key=True), + ) + + def test_actual_type(self): + eq_(str(self._col_type()), self._col_str) + + def test_reflect(self): + from sqlalchemy import inspect + insp = inspect(testing.db) + cols = insp.get_columns('data_table') + assert isinstance(cols[0]['type'], self._col_type) + + def _assert_data(self): + data = testing.db.execute( + select([self.tables.data_table.c.range]) + ).fetchall() + eq_(data, [(self._data_obj(), )]) + + def test_insert_obj(self): + testing.db.engine.execute( + self.tables.data_table.insert(), + {'range': self._data_obj()} + ) + self._assert_data() + + def test_insert_text(self): + testing.db.engine.execute( + self.tables.data_table.insert(), + {'range': self._data_str} + ) + self._assert_data() + +class Int4RangeTests(_RangeTypeMixin, fixtures.TablesTest): + + _col_type = INT4RANGE + _col_str = 'INT4RANGE' + _data_str = '[1,2)' + def _data_obj(self): + return self.extras.NumericRange(1, 2) + +class Int8RangeTests(_RangeTypeMixin, fixtures.TablesTest): + + _col_type = INT8RANGE + _col_str = 'INT8RANGE' + _data_str = '[9223372036854775806,9223372036854775807)' + def _data_obj(self): + return self.extras.NumericRange( + 9223372036854775806, 9223372036854775807 + ) + +class NumRangeTests(_RangeTypeMixin, fixtures.TablesTest): + + _col_type = NUMRANGE + _col_str = 'NUMRANGE' + _data_str = '[1.0,2.0)' + def _data_obj(self): + return self.extras.NumericRange( + decimal.Decimal('1.0'), decimal.Decimal('2.0') + ) + +class DateRangeTests(_RangeTypeMixin, fixtures.TablesTest): + + _col_type = DATERANGE + _col_str = 'DATERANGE' + _data_str = '[2013-03-23,2013-03-24)' + def _data_obj(self): + return self.extras.DateRange( + datetime.date(2013, 3, 23), datetime.date(2013, 3, 24) + ) + +class DateTimeRangeTests(_RangeTypeMixin, fixtures.TablesTest): + + _col_type = TSRANGE + _col_str = 'TSRANGE' + _data_str = '[2013-03-23 14:30,2013-03-23 23:30)' + def _data_obj(self): + return self.extras.DateTimeRange( + datetime.datetime(2013, 3, 23, 14, 30), + datetime.datetime(2013, 3, 23, 23, 30) + ) + +class DateTimeTZRangeTests(_RangeTypeMixin, fixtures.TablesTest): + + _col_type = TSTZRANGE + _col_str = 'TSTZRANGE' + + # make sure we use one, steady timestamp with timezone pair + # for all parts of all these tests + _tstzs = None + def tstzs(self): + if self._tstzs is None: + lower = testing.db.connect().scalar( + func.current_timestamp().select() + ) + upper = lower+datetime.timedelta(1) + self._tstzs = (lower, upper) + return self._tstzs + + @property + def _data_str(self): + return '[%s,%s)' % self.tstzs() + + def _data_obj(self): + return self.extras.DateTimeTZRange(*self.tstzs()) |