summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/testing/suite
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2016-11-22 15:36:32 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2016-11-22 16:39:16 -0500
commitdf9b6492e5ca47e26d539d2283fa816a2d5c8ad6 (patch)
treebf85a7744760077d38d9ad59043c68d95d80321c /lib/sqlalchemy/testing/suite
parent7de0d1785335961ce0f723877ca7a8fd85b2c0ca (diff)
downloadsqlalchemy-df9b6492e5ca47e26d539d2283fa816a2d5c8ad6.tar.gz
Ensure Variant passes along impl right-hand type
Fixed issue in :class:`.Variant` where the "right hand coercion" logic, inherited from :class:`.TypeDecorator`, would coerce the right-hand side into the :class:`.Variant` itself, rather than what the default type for the :class:`.Variant` would do. In the case of :class:`.Variant`, we want the type to act mostly like the base type so the default logic of :class:`.TypeDecorator` is now overridden to fall back to the underlying wrapped type's logic. Is mostly relevant for JSON at the moment. This patch additionally adds documentation and basic tests to allow for backend-agnostic comparison of JSON index elements to other objects. A future version should attempt to improve upon this by providing "astext", "asint" types of operators. Change-Id: I7b7b45d604a4ae8d1dc236a5a1248695aab5232e Fixes: #3859
Diffstat (limited to 'lib/sqlalchemy/testing/suite')
-rw-r--r--lib/sqlalchemy/testing/suite/test_types.py59
1 files changed, 53 insertions, 6 deletions
diff --git a/lib/sqlalchemy/testing/suite/test_types.py b/lib/sqlalchemy/testing/suite/test_types.py
index d85531396..dbbe03111 100644
--- a/lib/sqlalchemy/testing/suite/test_types.py
+++ b/lib/sqlalchemy/testing/suite/test_types.py
@@ -5,7 +5,7 @@ from ..assertions import eq_
from ..config import requirements
from sqlalchemy import Integer, Unicode, UnicodeText, select
from sqlalchemy import Date, DateTime, Time, MetaData, String, \
- Text, Numeric, Float, literal, Boolean, cast, null, JSON, and_
+ Text, Numeric, Float, literal, Boolean, cast, null, JSON, and_, type_coerce
from ..schema import Table, Column
from ... import testing
import decimal
@@ -623,6 +623,12 @@ class JSONTest(_LiteralRoundTripFixture, fixtures.TablesTest):
}
}
+ data6 = {
+ "a": 5,
+ "b": "some value",
+ "c": {"foo": "bar"}
+ }
+
@classmethod
def define_tables(cls, metadata):
Table('data_table', metadata,
@@ -730,10 +736,11 @@ class JSONTest(_LiteralRoundTripFixture, fixtures.TablesTest):
{"name": "r2", "data": self.data2},
{"name": "r3", "data": self.data3},
{"name": "r4", "data": self.data4},
- {"name": "r5", "data": self.data5}]
+ {"name": "r5", "data": self.data5},
+ {"name": "r6", "data": self.data6}]
)
- def _test_index_criteria(self, crit, expected):
+ def _test_index_criteria(self, crit, expected, test_literal=True):
self._criteria_fixture()
with config.db.connect() as conn:
stmt = select([self.tables.data_table.c.name]).where(crit)
@@ -743,10 +750,11 @@ class JSONTest(_LiteralRoundTripFixture, fixtures.TablesTest):
expected
)
- literal_sql = str(stmt.compile(
- config.db, compile_kwargs={"literal_binds": True}))
+ if test_literal:
+ literal_sql = str(stmt.compile(
+ config.db, compile_kwargs={"literal_binds": True}))
- eq_(conn.scalar(literal_sql), expected)
+ eq_(conn.scalar(literal_sql), expected)
def test_crit_spaces_in_key(self):
name = self.tables.data_table.c.name
@@ -791,6 +799,45 @@ class JSONTest(_LiteralRoundTripFixture, fixtures.TablesTest):
"r5"
)
+ def test_crit_against_string_basic(self):
+ name = self.tables.data_table.c.name
+ col = self.tables.data_table.c['data']
+
+ self._test_index_criteria(
+ and_(name == 'r6', cast(col["b"], String) == '"some value"'),
+ "r6"
+ )
+
+ def test_crit_against_string_coerce_type(self):
+ name = self.tables.data_table.c.name
+ col = self.tables.data_table.c['data']
+
+ self._test_index_criteria(
+ and_(name == 'r6',
+ cast(col["b"], String) == type_coerce("some value", JSON)),
+ "r6",
+ test_literal=False
+ )
+
+ def test_crit_against_int_basic(self):
+ name = self.tables.data_table.c.name
+ col = self.tables.data_table.c['data']
+
+ self._test_index_criteria(
+ and_(name == 'r6', cast(col["a"], String) == '5'),
+ "r6"
+ )
+
+ def test_crit_against_int_coerce_type(self):
+ name = self.tables.data_table.c.name
+ col = self.tables.data_table.c['data']
+
+ self._test_index_criteria(
+ and_(name == 'r6', cast(col["a"], String) == type_coerce(5, JSON)),
+ "r6",
+ test_literal=False
+ )
+
def test_unicode_round_trip(self):
s = select([
cast(