diff --git a/CHANGES.rst b/CHANGES.rst index 0fca53b..285de01 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,12 @@ Changelog Here you can see the full list of changes between each SQLAlchemy-Utils release. +0.30.7 (2015-05-28) +^^^^^^^^^^^^^^^^^^^ + +- Fix CompositeType null handling + + 0.30.6 (2015-05-28) ^^^^^^^^^^^^^^^^^^^ diff --git a/sqlalchemy_utils/__init__.py b/sqlalchemy_utils/__init__.py index 8704971..16c3548 100644 --- a/sqlalchemy_utils/__init__.py +++ b/sqlalchemy_utils/__init__.py @@ -90,4 +90,4 @@ from .types import ( # noqa WeekDaysType ) -__version__ = '0.30.6' +__version__ = '0.30.7' diff --git a/sqlalchemy_utils/types/pg_composite.py b/sqlalchemy_utils/types/pg_composite.py index c838f07..255e0d8 100644 --- a/sqlalchemy_utils/types/pg_composite.py +++ b/sqlalchemy_utils/types/pg_composite.py @@ -204,6 +204,8 @@ class CompositeType(UserDefinedType, SchemaType): def bind_processor(self, dialect): def process(value): + if value is None: + return None processed_value = [] for i, column in enumerate(self.columns): if isinstance(column.type, TypeDecorator): @@ -219,6 +221,8 @@ class CompositeType(UserDefinedType, SchemaType): def result_processor(self, dialect, coltype): def process(value): + if value is None: + return None cls = value.__class__ kwargs = {} for column in self.columns: diff --git a/tests/types/test_composite.py b/tests/types/test_composite.py index 885b3da..9f67272 100644 --- a/tests/types/test_composite.py +++ b/tests/types/test_composite.py @@ -219,6 +219,35 @@ class TestCompositeTypeWithRangeTypeInsideArray(TestCase): ) assert account.categories[1].name == 'good' + def test_parameter_processing_with_nulls_as_composite_fields(self): + account = self.Account( + categories=[ + (None, 'bad'), + (intervals.DecimalInterval([18, 20]), None) + ] + ) + self.session.add(account) + self.session.commit() + assert account.categories[0].scale is None + assert account.categories[0].name == 'bad' + assert ( + account.categories[1].scale == intervals.DecimalInterval([18, 20]) + ) + assert account.categories[1].name is None + + def test_parameter_processing_with_nulls_as_composites(self): + account = self.Account( + categories=[ + (None, None), + None + ] + ) + self.session.add(account) + self.session.commit() + assert account.categories[0].scale is None + assert account.categories[0].name is None + assert account.categories[1] is None + class TestCompositeTypeWhenTypeAlreadyExistsInDatabase(TestCase): dns = 'postgres://postgres@localhost/sqlalchemy_utils_test'