--- /dev/null
+.. change::
+ :tags: change, postgresql
+ :tickets: 10821
+
+ The :meth:`_types.ARRAY.Comparator.any` and
+ :meth:`_types.ARRAY.Comparator.all` methods for the :class:`_types.ARRAY`
+ type are now deprecated for removal; these two methods along with
+ :func:`_postgresql.Any` and :func:`_postgresql.All` have been legacy for
+ some time as they are superseded by the :func:`_sql.any_` and
+ :func:`_sql.all_` functions, which feature more intutive use.
+
"""A synonym for the ARRAY-level :meth:`.ARRAY.Comparator.any` method.
See that method for details.
+ .. deprecated:: 2.1
+
+ The :meth:`_types.ARRAY.Comparator.any` and
+ :meth:`_types.ARRAY.Comparator.all` methods for arrays are deprecated
+ for removal, along with the PG-specific :func:`_postgresql.Any` and
+ :func:`_postgresql.All` functions. See :func:`_sql.any_` and
+ :func:`_sql.all_` functions for modern use.
+
+
"""
return arrexpr.any(other, operator) # type: ignore[no-any-return, union-attr] # noqa: E501
"""A synonym for the ARRAY-level :meth:`.ARRAY.Comparator.all` method.
See that method for details.
+ .. deprecated:: 2.1
+
+ The :meth:`_types.ARRAY.Comparator.any` and
+ :meth:`_types.ARRAY.Comparator.all` methods for arrays are deprecated
+ for removal, along with the PG-specific :func:`_postgresql.Any` and
+ :func:`_postgresql.All` functions. See :func:`_sql.any_` and
+ :func:`_sql.all_` functions for modern use.
+
"""
return arrexpr.all(other, operator) # type: ignore[no-any-return, union-attr] # noqa: E501
# would render 'NULL = ALL(somearray)'
all_(mytable.c.somearray) == None
- .. versionchanged:: 1.4.26 repaired the use of any_() / all_()
- comparing to NULL on the right side to be flipped to the left.
-
The column-level :meth:`_sql.ColumnElement.all_` method (not to be
- confused with :class:`_types.ARRAY` level
+ confused with the deprecated :class:`_types.ARRAY` level
:meth:`_types.ARRAY.Comparator.all`) is shorthand for
``all_(col)``::
# would render 'NULL = ANY(somearray)'
any_(mytable.c.somearray) == None
- .. versionchanged:: 1.4.26 repaired the use of any_() / all_()
- comparing to NULL on the right side to be flipped to the left.
-
The column-level :meth:`_sql.ColumnElement.any_` method (not to be
- confused with :class:`_types.ARRAY` level
+ confused with the deprecated :class:`_types.ARRAY` level
:meth:`_types.ARRAY.Comparator.any`) is shorthand for
``any_(col)``::
"ARRAY type; please use the dialect-specific ARRAY type"
)
+ @util.deprecated(
+ "2.1",
+ message="The :meth:`_types.ARRAY.Comparator.any` and "
+ ":meth:`_types.ARRAY.Comparator.all` methods for arrays are "
+ "deprecated for removal, along with the PG-specific "
+ ":func:`_postgresql.Any` and "
+ ":func:`_postgresql.All` functions. See :func:`_sql.any_` and "
+ ":func:`_sql.all_` functions for modern use.",
+ )
@util.preload_module("sqlalchemy.sql.elements")
def any(
self, other: Any, operator: Optional[OperatorType] = None
) -> ColumnElement[bool]:
"""Return ``other operator ANY (array)`` clause.
- .. legacy:: This method is an :class:`_types.ARRAY` - specific
- construct that is now superseded by the :func:`_sql.any_`
- function, which features a different calling style. The
- :func:`_sql.any_` function is also mirrored at the method level
- via the :meth:`_sql.ColumnOperators.any_` method.
-
Usage of array-specific :meth:`_types.ARRAY.Comparator.any`
is as follows::
),
)
+ @util.deprecated(
+ "2.1",
+ message="The :meth:`_types.ARRAY.Comparator.any` and "
+ ":meth:`_types.ARRAY.Comparator.all` methods for arrays are "
+ "deprecated for removal, along with the PG-specific "
+ ":func:`_postgresql.Any` and "
+ ":func:`_postgresql.All` functions. See :func:`_sql.any_` and "
+ ":func:`_sql.all_` functions for modern use.",
+ )
@util.preload_module("sqlalchemy.sql.elements")
def all(
self, other: Any, operator: Optional[OperatorType] = None
) -> ColumnElement[bool]:
"""Return ``other operator ALL (array)`` clause.
- .. legacy:: This method is an :class:`_types.ARRAY` - specific
- construct that is now superseded by the :func:`_sql.all_`
- function, which features a different calling style. The
- :func:`_sql.all_` function is also mirrored at the method level
- via the :meth:`_sql.ColumnOperators.all_` method.
-
Usage of array-specific :meth:`_types.ARRAY.Comparator.all`
is as follows::
import random
import re
+from sqlalchemy import all_
from sqlalchemy import and_
+from sqlalchemy import any_
from sqlalchemy import BigInteger
from sqlalchemy import bindparam
from sqlalchemy import case
x, """SELECT pg_table.col1, pg_table."variadic" FROM pg_table"""
)
+ def _array_any_deprecation(self):
+ return testing.expect_deprecated(
+ r"The ARRAY.Comparator.any\(\) and "
+ r"ARRAY.Comparator.all\(\) methods "
+ r"for arrays are deprecated for removal, along with the "
+ r"PG-specific Any\(\) "
+ r"and All\(\) functions. See any_\(\) and all_\(\) functions for "
+ "modern use. "
+ )
+
def test_array(self):
c = Column("x", postgresql.ARRAY(Integer))
checkparams={"x_1": [3]},
dialect=PGDialect_psycopg2(),
)
+
+ def test_array_modern_any_all(self):
+ c = Column("x", postgresql.ARRAY(Integer))
+
self.assert_compile(
- postgresql.Any(4, c),
- "%(x_1)s = ANY (x)",
- checkparams={"x_1": 4},
+ 4 == c.any_(),
+ "%(param_1)s = ANY (x)",
+ checkparams={"param_1": 4},
)
self.assert_compile(
- c.any(5),
- "%(x_1)s = ANY (x)",
- checkparams={"x_1": 5},
+ 5 == any_(c),
+ "%(param_1)s = ANY (x)",
+ checkparams={"param_1": 5},
)
self.assert_compile(
- ~c.any(5),
- "NOT (%(x_1)s = ANY (x))",
- checkparams={"x_1": 5},
+ ~(c.any_() == 5),
+ "NOT (%(param_1)s = ANY (x))",
+ checkparams={"param_1": 5},
)
self.assert_compile(
- c.all(5),
- "%(x_1)s = ALL (x)",
- checkparams={"x_1": 5},
+ ~(5 == c.any_()),
+ "NOT (%(param_1)s = ANY (x))",
+ checkparams={"param_1": 5},
)
self.assert_compile(
- ~c.all(5),
- "NOT (%(x_1)s = ALL (x))",
- checkparams={"x_1": 5},
+ 5 != any_(c),
+ "%(param_1)s != ANY (x)",
+ checkparams={"param_1": 5},
)
self.assert_compile(
- c.any(5, operator=operators.ne),
- "%(x_1)s != ANY (x)",
- checkparams={"x_1": 5},
+ 6 > all_(c),
+ "%(param_1)s > ALL (x)",
+ checkparams={"param_1": 6},
)
+
self.assert_compile(
- postgresql.All(6, c, operator=operators.gt),
- "%(x_1)s > ALL (x)",
- checkparams={"x_1": 6},
+ 7 < all_(c),
+ "%(param_1)s < ALL (x)",
+ checkparams={"param_1": 7},
)
+
self.assert_compile(
- c.all(7, operator=operators.lt),
- "%(x_1)s < ALL (x)",
- checkparams={"x_1": 7},
+ c.all_() == 5,
+ "%(param_1)s = ALL (x)",
+ checkparams={"param_1": 5},
)
+ self.assert_compile(
+ 5 == c.all_(),
+ "%(param_1)s = ALL (x)",
+ checkparams={"param_1": 5},
+ )
+
+ self.assert_compile(
+ ~(5 == all_(c)),
+ "NOT (%(param_1)s = ALL (x))",
+ checkparams={"param_1": 5},
+ )
+
+ self.assert_compile(
+ ~(all_(c) == 5),
+ "NOT (%(param_1)s = ALL (x))",
+ checkparams={"param_1": 5},
+ )
+
+ def test_array_deprecated_any_all(self):
+ c = Column("x", postgresql.ARRAY(Integer))
+
+ with self._array_any_deprecation():
+ self.assert_compile(
+ postgresql.Any(4, c),
+ "%(x_1)s = ANY (x)",
+ checkparams={"x_1": 4},
+ )
+
+ with self._array_any_deprecation():
+ self.assert_compile(
+ c.any(5),
+ "%(x_1)s = ANY (x)",
+ checkparams={"x_1": 5},
+ )
+
+ with self._array_any_deprecation():
+ self.assert_compile(
+ ~c.any(5),
+ "NOT (%(x_1)s = ANY (x))",
+ checkparams={"x_1": 5},
+ )
+
+ with self._array_any_deprecation():
+ self.assert_compile(
+ c.any(5, operator=operators.ne),
+ "%(x_1)s != ANY (x)",
+ checkparams={"x_1": 5},
+ )
+
+ with self._array_any_deprecation():
+ self.assert_compile(
+ postgresql.All(6, c, operator=operators.gt),
+ "%(x_1)s > ALL (x)",
+ checkparams={"x_1": 6},
+ )
+
+ with self._array_any_deprecation():
+ self.assert_compile(
+ c.all(7, operator=operators.lt),
+ "%(x_1)s < ALL (x)",
+ checkparams={"x_1": 7},
+ )
+
+ with self._array_any_deprecation():
+ self.assert_compile(
+ c.all(5),
+ "%(x_1)s = ALL (x)",
+ checkparams={"x_1": 5},
+ )
+
+ with self._array_any_deprecation():
+ self.assert_compile(
+ ~c.all(5),
+ "NOT (%(x_1)s = ALL (x))",
+ checkparams={"x_1": 5},
+ )
+
@testing.combinations(
(lambda c: c.overlap, "&&"),
(lambda c: c.contains, "@>"),
from ...engine.test_ddlevents import DDLEventWCreateHarness
+def _array_any_deprecation():
+ return testing.expect_deprecated(
+ r"The ARRAY.Comparator.any\(\) and "
+ r"ARRAY.Comparator.all\(\) methods "
+ r"for arrays are deprecated for removal, along with the "
+ r"PG-specific Any\(\) "
+ r"and All\(\) functions. See any_\(\) and all_\(\) functions for "
+ "modern use. "
+ )
+
+
class MiscTypesTest(AssertsCompiledSQL, fixtures.TestBase):
__dialect__ = postgresql.dialect()
checkparams={"x_1": 3},
)
- def test_array_any(self):
+ def test_array_deprecated_any(self):
col = column("x", postgresql.ARRAY(Integer))
- self.assert_compile(
- select(col.any(7, operator=operators.lt)),
- "SELECT %(x_1)s < ANY (x) AS anon_1",
- checkparams={"x_1": 7},
- )
- def test_array_all(self):
+ with _array_any_deprecation():
+ self.assert_compile(
+ select(col.any(7, operator=operators.lt)),
+ "SELECT %(x_1)s < ANY (x) AS anon_1",
+ checkparams={"x_1": 7},
+ )
+
+ def test_array_deprecated_all(self):
col = column("x", postgresql.ARRAY(Integer))
- self.assert_compile(
- select(col.all(7, operator=operators.lt)),
- "SELECT %(x_1)s < ALL (x) AS anon_1",
- checkparams={"x_1": 7},
- )
+
+ with _array_any_deprecation():
+ self.assert_compile(
+ select(col.all(7, operator=operators.lt)),
+ "SELECT %(x_1)s < ALL (x) AS anon_1",
+ checkparams={"x_1": 7},
+ )
def test_array_contains(self):
col = column("x", postgresql.ARRAY(Integer))
connection.execute(arrtable.insert(), dict(intarr=[4, 5, 6]))
eq_(
connection.scalar(
- select(arrtable.c.intarr).where(
- postgresql.Any(5, arrtable.c.intarr)
- )
+ select(arrtable.c.intarr).where(5 == any_(arrtable.c.intarr))
),
[4, 5, 6],
)
def test_array_all_exec(self, connection):
arrtable = self.tables.arrtable
connection.execute(arrtable.insert(), dict(intarr=[4, 5, 6]))
+
eq_(
connection.scalar(
- select(arrtable.c.intarr).where(
- arrtable.c.intarr.all(4, operator=operators.le)
- )
+ select(arrtable.c.intarr).where(4 <= all_(arrtable.c.intarr))
),
[4, 5, 6],
)
+ def test_array_any_deprecated_exec(self, connection):
+ arrtable = self.tables.arrtable
+ connection.execute(arrtable.insert(), dict(intarr=[4, 5, 6]))
+
+ with _array_any_deprecation():
+ eq_(
+ connection.scalar(
+ select(arrtable.c.intarr).where(
+ postgresql.Any(5, arrtable.c.intarr)
+ )
+ ),
+ [4, 5, 6],
+ )
+
+ def test_array_all_deprecated_exec(self, connection):
+ arrtable = self.tables.arrtable
+ connection.execute(arrtable.insert(), dict(intarr=[4, 5, 6]))
+
+ with _array_any_deprecation():
+ eq_(
+ connection.scalar(
+ select(arrtable.c.intarr).where(
+ postgresql.All(
+ 4, arrtable.c.intarr, operator=operators.le
+ )
+ )
+ ),
+ [4, 5, 6],
+ )
+
def test_tuple_flag(self, connection, metadata):
t1 = Table(
"t1",
@_enum_combinations
@testing.combinations("all", "any", argnames="fn")
- def test_any_all_legacy_roundtrip(
+ def test_any_all_deprecated_roundtrip(
self, array_of_enum_fixture, connection, array_cls, enum_cls, fn
):
"""test #6515"""
tbl, MyEnum = array_of_enum_fixture(array_cls, enum_cls)
- if fn == "all":
- expr = tbl.c.pyenum_col.all(MyEnum.b)
- result = [([MyEnum.b],)]
- elif fn == "any":
- expr = tbl.c.pyenum_col.any(MyEnum.b)
- result = [([MyEnum.a, MyEnum.b],), ([MyEnum.b],)]
- else:
- assert False
+ with _array_any_deprecation():
+ if fn == "all":
+ expr = tbl.c.pyenum_col.all(MyEnum.b)
+ result = [([MyEnum.b],)]
+ elif fn == "any":
+ expr = tbl.c.pyenum_col.any(MyEnum.b)
+ result = [([MyEnum.a, MyEnum.b],), ([MyEnum.b],)]
+ else:
+ assert False
sel = select(tbl.c.pyenum_col).where(expr).order_by(tbl.c.id)
eq_(connection.execute(sel).fetchall(), result)
# of String
assert isinstance(boolean_expr.left.type, expected_type_affinity)
- @testing.variation("operator", ["any", "all"])
- @testing.variation("datatype", ["array", "arraystring", "arrayenum"])
- def test_what_type_is_legacy_any_all(
- self,
- datatype: testing.Variation,
- t_fixture,
- operator: testing.Variation,
- ):
- if datatype.array:
- col = t_fixture.c.arrval
- value = 25
- expected_type_affinity = Integer
- elif datatype.arraystring:
- col = t_fixture.c.arrstring
- value = "a string"
- expected_type_affinity = String
- elif datatype.arrayenum:
- col = t_fixture.c.arrenum
- value = MyEnum.TWO
- expected_type_affinity = Enum
- else:
- datatype.fail()
-
- if operator.any:
- boolean_expr = col.any(value)
- elif operator.all:
- boolean_expr = col.all(value)
- else:
- operator.fail()
-
- # using isinstance so things work out for Enum which has type affinity
- # of String
- assert isinstance(boolean_expr.left.type, expected_type_affinity)
-
@testing.fixture(
params=[
("ANY", any_),
def any_all_operators(self, request):
return request.param
- # test legacy array any() / all(). these are superseded by the
- # any_() / all_() versions
- @testing.fixture(
- params=[
- ("ANY", lambda x, *o: x.any(*o)),
- ("ALL", lambda x, *o: x.all(*o)),
- ]
- )
- def legacy_any_all_operators(self, request):
- return request.param
-
def test_array(self, t_fixture, any_all_operators):
t = t_fixture
op, fn = any_all_operators
t.c.data + fn(t.c.arrval), f"tab1.data + {op} (tab1.arrval)"
)
- def test_bindparam_coercion(self, t_fixture, legacy_any_all_operators):
- """test #7979"""
- t = t_fixture
- op, fn = legacy_any_all_operators
-
- expr = fn(t.c.arrval, bindparam("param"))
- expected = f"%(param)s = {op} (tab1.arrval)"
- is_(expr.left.type._type_affinity, Integer)
-
- self.assert_compile(expr, expected, dialect="postgresql")
-
- def test_array_comparator_accessor(
- self, t_fixture, legacy_any_all_operators
- ):
- t = t_fixture
- op, fn = legacy_any_all_operators
-
- self.assert_compile(
- fn(t.c.arrval, 5, operator.gt),
- f":arrval_1 > {op} (tab1.arrval)",
- checkparams={"arrval_1": 5},
- )
-
- def test_array_comparator_negate_accessor(
- self, t_fixture, legacy_any_all_operators
- ):
- t = t_fixture
- op, fn = legacy_any_all_operators
-
- self.assert_compile(
- ~fn(t.c.arrval, 5, operator.gt),
- f"NOT (:arrval_1 > {op} (tab1.arrval))",
- checkparams={"arrval_1": 5},
- )
-
def test_array_expression(self, t_fixture, any_all_operators):
t = t_fixture
op, fn = any_all_operators
fn(values(t.c.data).data([(1,), (42,)]))
+class DeprecatedAnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL):
+ __dialect__ = "default"
+
+ @testing.fixture
+ def t_fixture(self):
+ m = MetaData()
+
+ t = Table(
+ "tab1",
+ m,
+ Column("arrval", ARRAY(Integer)),
+ Column("arrenum", ARRAY(Enum(MyEnum))),
+ Column("arrstring", ARRAY(String)),
+ Column("data", Integer),
+ )
+ return t
+
+ # test legacy array any() / all(). these are superseded by the
+ # any_() / all_() versions
+ @testing.fixture(
+ params=[
+ ("ANY", lambda x, *o: x.any(*o)),
+ ("ALL", lambda x, *o: x.all(*o)),
+ ]
+ )
+ def legacy_any_all_operators(self, request):
+ return request.param
+
+ def _array_any_deprecation(self):
+ return testing.expect_deprecated(
+ r"The ARRAY.Comparator.any\(\) and "
+ r"ARRAY.Comparator.all\(\) methods "
+ r"for arrays are deprecated for removal, along with the "
+ r"PG-specific Any\(\) "
+ r"and All\(\) functions. See any_\(\) and all_\(\) functions for "
+ "modern use. "
+ )
+
+ @testing.variation("operator", ["any", "all"])
+ @testing.variation("datatype", ["array", "arraystring", "arrayenum"])
+ def test_what_type_is_legacy_any_all(
+ self,
+ datatype: testing.Variation,
+ t_fixture,
+ operator: testing.Variation,
+ ):
+ if datatype.array:
+ col = t_fixture.c.arrval
+ value = 25
+ expected_type_affinity = Integer
+ elif datatype.arraystring:
+ col = t_fixture.c.arrstring
+ value = "a string"
+ expected_type_affinity = String
+ elif datatype.arrayenum:
+ col = t_fixture.c.arrenum
+ value = MyEnum.TWO
+ expected_type_affinity = Enum
+ else:
+ datatype.fail()
+
+ with self._array_any_deprecation():
+ if operator.any:
+ boolean_expr = col.any(value)
+ elif operator.all:
+ boolean_expr = col.all(value)
+ else:
+ operator.fail()
+
+ # using isinstance so things work out for Enum which has type affinity
+ # of String
+ assert isinstance(boolean_expr.left.type, expected_type_affinity)
+
+ def test_bindparam_coercion(self, t_fixture, legacy_any_all_operators):
+ """test #7979"""
+ t = t_fixture
+ op, fn = legacy_any_all_operators
+
+ with self._array_any_deprecation():
+ expr = fn(t.c.arrval, bindparam("param"))
+ expected = f"%(param)s = {op} (tab1.arrval)"
+ is_(expr.left.type._type_affinity, Integer)
+
+ self.assert_compile(expr, expected, dialect="postgresql")
+
+ def test_array_comparator_accessor(
+ self, t_fixture, legacy_any_all_operators
+ ):
+ t = t_fixture
+ op, fn = legacy_any_all_operators
+
+ with self._array_any_deprecation():
+ self.assert_compile(
+ fn(t.c.arrval, 5, operator.gt),
+ f":arrval_1 > {op} (tab1.arrval)",
+ checkparams={"arrval_1": 5},
+ )
+
+ def test_array_comparator_negate_accessor(
+ self, t_fixture, legacy_any_all_operators
+ ):
+ t = t_fixture
+ op, fn = legacy_any_all_operators
+
+ with self._array_any_deprecation():
+ self.assert_compile(
+ ~fn(t.c.arrval, 5, operator.gt),
+ f"NOT (:arrval_1 > {op} (tab1.arrval))",
+ checkparams={"arrval_1": 5},
+ )
+
+
class BitOpTest(fixtures.TestBase, testing.AssertsCompiledSQL):
__dialect__ = "default"
eq_(expr2.right.type._type_affinity, Integer)
self.assert_compile(
- column("q", ArrayDec).any(7, operator=operators.lt),
- "%(q_1)s < ANY (q)",
+ 7 < column("q", ArrayDec).any_(),
+ "%(param_1)s < ANY (q)",
dialect="postgresql",
)