From: sanjana Date: Wed, 13 Feb 2019 15:17:46 +0000 (-0500) Subject: Adding setter to should_evaluate_none property X-Git-Tag: rel_1_3_0~17^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=12dad561a77506fe262d791d3135babc0be50e66;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Adding setter to should_evaluate_none property Fixed issue where the :class:`.JSON` type had a read-only :attr:`.JSON.should_evaluate_none` attribute, which would cause failures when making use of the :meth:`.TypeEngine.evaluates_none` method in conjunction with this type. Pull request courtesy Sanjana S. Fixes: #4485 Closes: #4496 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/4496 Pull-request-sha: 044beb23982d411be6fe640716b1b693df0f7189 Change-Id: I1f3e1d7dec9d2ceb6ccaaa8cac158a062cf02710 --- diff --git a/doc/build/changelog/unreleased_12/4485.rst b/doc/build/changelog/unreleased_12/4485.rst new file mode 100644 index 0000000000..dc5860440a --- /dev/null +++ b/doc/build/changelog/unreleased_12/4485.rst @@ -0,0 +1,8 @@ +.. change:: + :tags: bug, sql + :tickets: 4485 + + Fixed issue where the :class:`.JSON` type had a read-only + :attr:`.JSON.should_evaluate_none` attribute, which would cause failures + when making use of the :meth:`.TypeEngine.evaluates_none` method in + conjunction with this type. Pull request courtesy Sanjana S. diff --git a/lib/sqlalchemy/sql/sqltypes.py b/lib/sqlalchemy/sql/sqltypes.py index 8798f5ad77..0d39445527 100644 --- a/lib/sqlalchemy/sql/sqltypes.py +++ b/lib/sqlalchemy/sql/sqltypes.py @@ -2214,8 +2214,13 @@ class JSON(Indexable, TypeEngine): @property def should_evaluate_none(self): + """Alias of :attr:`.JSON.none_as_null`""" return not self.none_as_null + @should_evaluate_none.setter + def should_evaluate_none(self, value): + self.none_as_null = not value + @util.memoized_property def _str_impl(self): return String(_expect_unicode=True) diff --git a/test/orm/test_unitofworkv2.py b/test/orm/test_unitofworkv2.py index 0a58bb57ae..9d7879bb24 100644 --- a/test/orm/test_unitofworkv2.py +++ b/test/orm/test_unitofworkv2.py @@ -1,9 +1,11 @@ +from sqlalchemy import cast from sqlalchemy import event from sqlalchemy import exc from sqlalchemy import FetchedValue from sqlalchemy import ForeignKey from sqlalchemy import func from sqlalchemy import Integer +from sqlalchemy import JSON from sqlalchemy import literal from sqlalchemy import select from sqlalchemy import String @@ -2669,6 +2671,20 @@ class NullEvaluatingTest(fixtures.MappedTest, testing.AssertsExecutionResults): ), ) + if testing.requires.json_type.enabled: + Table( + "test_has_json", + metadata, + Column( + "id", + Integer, + primary_key=True, + test_needs_autoincrement=True, + ), + Column("data", JSON(none_as_null=True).evaluates_none()), + Column("data_null", JSON(none_as_null=True)), + ) + @classmethod def setup_classes(cls): class Thing(cls.Basic): @@ -2677,6 +2693,9 @@ class NullEvaluatingTest(fixtures.MappedTest, testing.AssertsExecutionResults): class AltNameThing(cls.Basic): pass + class JSONThing(cls.Basic): + pass + @classmethod def setup_mappers(cls): Thing = cls.classes.Thing @@ -2686,6 +2705,9 @@ class NullEvaluatingTest(fixtures.MappedTest, testing.AssertsExecutionResults): mapper(AltNameThing, cls.tables.test_w_renames, column_prefix="_foo_") + if testing.requires.json_type.enabled: + mapper(cls.classes.JSONThing, cls.tables.test_has_json) + def _assert_col(self, name, value): Thing, AltNameThing = self.classes.Thing, self.classes.AltNameThing s = Session() @@ -2819,3 +2841,14 @@ class NullEvaluatingTest(fixtures.MappedTest, testing.AssertsExecutionResults): self._test_bulk_insert_novalue( "builtin_evals_null_default", "default_val" ) + + @testing.requires.json_type + def test_json_none_as_null(self): + JSONThing = self.classes.JSONThing + + s = Session() + f1 = JSONThing(data=None, data_null=None) + s.add(f1) + s.commit() + eq_(s.query(cast(JSONThing.data, String)).scalar(), "null") + eq_(s.query(cast(JSONThing.data_null, String)).scalar(), None) diff --git a/test/sql/test_types.py b/test/sql/test_types.py index dc75e1b14a..a1b1f024b9 100644 --- a/test/sql/test_types.py +++ b/test/sql/test_types.py @@ -249,6 +249,8 @@ class AdaptTest(fixtures.TestBase): or t1.__dict__[k] is None ) + eq_(t1.evaluates_none().should_evaluate_none, True) + def test_python_type(self): eq_(types.Integer().python_type, int) eq_(types.Numeric().python_type, decimal.Decimal)