from sqlalchemy import update
from sqlalchemy import VARCHAR
from sqlalchemy.dialects import postgresql
-from sqlalchemy.dialects.postgresql import aggregate_order_by
from sqlalchemy.dialects.postgresql import ARRAY as PG_ARRAY
from sqlalchemy.dialects.postgresql import array
from sqlalchemy.dialects.postgresql import array_agg as pg_array_agg
from sqlalchemy.sql import literal_column
from sqlalchemy.sql import operators
from sqlalchemy.sql import table
-from sqlalchemy.sql import util as sql_util
from sqlalchemy.sql.functions import GenericFunction
from sqlalchemy.testing import expect_raises
from sqlalchemy.testing import expect_raises_message
dialect=postgresql.dialect(),
)
- def test_aggregate_order_by_one(self):
- m = MetaData()
- table = Table("table1", m, Column("a", Integer), Column("b", Integer))
- expr = func.array_agg(aggregate_order_by(table.c.a, table.c.b.desc()))
- stmt = select(expr)
-
- # note this tests that the object exports FROM objects
- # correctly
- self.assert_compile(
- stmt,
- "SELECT array_agg(table1.a ORDER BY table1.b DESC) "
- "AS array_agg_1 FROM table1",
- )
-
- def test_aggregate_order_by_two(self):
- m = MetaData()
- table = Table("table1", m, Column("a", Integer), Column("b", Integer))
- expr = func.string_agg(
- table.c.a, aggregate_order_by(literal_column("','"), table.c.a)
- )
- stmt = select(expr)
-
- self.assert_compile(
- stmt,
- "SELECT string_agg(table1.a, ',' ORDER BY table1.a) "
- "AS string_agg_1 FROM table1",
- )
-
- def test_aggregate_order_by_multi_col(self):
- m = MetaData()
- table = Table("table1", m, Column("a", Integer), Column("b", Integer))
- expr = func.string_agg(
- table.c.a,
- aggregate_order_by(
- literal_column("','"), table.c.a, table.c.b.desc()
- ),
- )
- stmt = select(expr)
-
- self.assert_compile(
- stmt,
- "SELECT string_agg(table1.a, "
- "',' ORDER BY table1.a, table1.b DESC) "
- "AS string_agg_1 FROM table1",
- )
-
- def test_aggregate_orcer_by_no_arg(self):
- assert_raises_message(
- TypeError,
- "at least one ORDER BY element is required",
- aggregate_order_by,
- literal_column("','"),
- )
-
def test_pg_array_agg_implicit_pg_array(self):
expr = pg_array_agg(column("data", Integer))
assert isinstance(expr.type, PG_ARRAY)
assert isinstance(expr.type, PG_ARRAY)
is_(expr.type.item_type._type_affinity, Integer)
- def test_aggregate_order_by_adapt(self):
- m = MetaData()
- table = Table("table1", m, Column("a", Integer), Column("b", Integer))
- expr = func.array_agg(aggregate_order_by(table.c.a, table.c.b.desc()))
- stmt = select(expr)
-
- a1 = table.alias("foo")
- stmt2 = sql_util.ClauseAdapter(a1).traverse(stmt)
- self.assert_compile(
- stmt2,
- "SELECT array_agg(foo.a ORDER BY foo.b DESC) AS array_agg_1 "
- "FROM table1 AS foo",
- )
-
def test_array_agg_w_filter_subscript(self):
series = func.generate_series(1, 100).alias("series")
series_col = column("series")
class CacheKeyTest(fixtures.CacheKeyFixture, fixtures.TestBase):
- def test_aggregate_order_by(self):
- """test #8574"""
-
- self._run_cache_key_fixture(
- lambda: (
- aggregate_order_by(column("a"), column("a")),
- aggregate_order_by(column("a"), column("b")),
- aggregate_order_by(column("a"), column("a").desc()),
- aggregate_order_by(column("a"), column("a").nulls_first()),
- aggregate_order_by(
- column("a"), column("a").desc().nulls_first()
- ),
- aggregate_order_by(column("a", Integer), column("b")),
- aggregate_order_by(column("a"), column("b"), column("c")),
- aggregate_order_by(column("a"), column("c"), column("b")),
- aggregate_order_by(
- column("a"), column("b").desc(), column("c")
- ),
- aggregate_order_by(
- column("a"), column("b").nulls_first(), column("c")
- ),
- aggregate_order_by(
- column("a"), column("b").desc().nulls_first(), column("c")
- ),
- aggregate_order_by(
- column("a", Integer), column("a"), column("b")
- ),
- ),
- compare_values=False,
- )
-
def test_array_equivalent_keys_one_element(self):
self._run_cache_key_equal_fixture(
lambda: (
from sqlalchemy import Unicode
from sqlalchemy import util
from sqlalchemy.dialects import postgresql
-from sqlalchemy.dialects.postgresql import aggregate_order_by
from sqlalchemy.dialects.postgresql import array
from sqlalchemy.dialects.postgresql import array_agg
from sqlalchemy.dialects.postgresql import asyncpg
from sqlalchemy.exc import DBAPIError
from sqlalchemy.orm import declarative_base
from sqlalchemy.orm import Session
+from sqlalchemy.sql import aggregate_order_by
from sqlalchemy.sql import bindparam
from sqlalchemy.sql import operators
from sqlalchemy.sql import sqltypes
from sqlalchemy.dialects import mysql
from sqlalchemy.dialects import postgresql
from sqlalchemy.schema import Sequence
+from sqlalchemy.sql import aggregate_order_by
from sqlalchemy.sql import bindparam
from sqlalchemy.sql import ColumnElement
from sqlalchemy.sql import dml
is_not(ck1, None)
is_not(ck3, None)
+ def test_aggregate_order_by(self):
+ """test #8574"""
+
+ self._run_cache_key_fixture(
+ lambda: (
+ aggregate_order_by(column("a"), column("a")),
+ aggregate_order_by(column("a"), column("b")),
+ aggregate_order_by(column("a"), column("a").desc()),
+ aggregate_order_by(column("a"), column("a").nulls_first()),
+ aggregate_order_by(
+ column("a"), column("a").desc().nulls_first()
+ ),
+ aggregate_order_by(column("a", Integer), column("b")),
+ aggregate_order_by(column("a"), column("b"), column("c")),
+ aggregate_order_by(column("a"), column("c"), column("b")),
+ aggregate_order_by(
+ column("a"), column("b").desc(), column("c")
+ ),
+ aggregate_order_by(
+ column("a"), column("b").nulls_first(), column("c")
+ ),
+ aggregate_order_by(
+ column("a"), column("b").desc().nulls_first(), column("c")
+ ),
+ aggregate_order_by(
+ column("a", Integer), column("a"), column("b")
+ ),
+ ),
+ compare_values=False,
+ )
+
def all_hascachekey_subclasses(ignore_subclasses=()):
def find_subclasses(cls: type):
from sqlalchemy import JSON
from sqlalchemy import literal
from sqlalchemy import literal_column
+from sqlalchemy import MetaData
from sqlalchemy import Numeric
from sqlalchemy import select
from sqlalchemy import Sequence
from sqlalchemy.dialects.postgresql import ARRAY as PG_ARRAY
from sqlalchemy.dialects.postgresql import array
from sqlalchemy.ext.compiler import compiles
+from sqlalchemy.sql import aggregate_order_by
from sqlalchemy.sql import column
from sqlalchemy.sql import functions
from sqlalchemy.sql import LABEL_STYLE_TABLENAME_PLUS_COL
from sqlalchemy.sql import quoted_name
from sqlalchemy.sql import sqltypes
from sqlalchemy.sql import table
+from sqlalchemy.sql import util
from sqlalchemy.sql.compiler import BIND_TEMPLATES
from sqlalchemy.sql.functions import FunctionElement
from sqlalchemy.sql.functions import GenericFunction
},
)
+ def test_aggregate_order_by_one(self):
+ table = Table("table1", MetaData(), Column("a", Integer), Column("b", Integer))
+ expr = func.array_agg(aggregate_order_by(table.c.a, table.c.b.desc()))
+ stmt = select(expr)
+
+ # note this tests that the object exports FROM objects
+ # correctly
+ self.assert_compile(
+ stmt,
+ "SELECT array_agg(table1.a ORDER BY table1.b DESC) "
+ "AS array_agg_1 FROM table1",
+ )
+
+ def test_aggregate_order_by_two(self):
+ table = Table("table1", MetaData(), Column("a", Integer), Column("b", Integer))
+ expr = func.string_agg(
+ table.c.a, aggregate_order_by(literal_column("','"), table.c.a)
+ )
+ stmt = select(expr)
+
+ self.assert_compile(
+ stmt,
+ "SELECT string_agg(table1.a, ',' ORDER BY table1.a) "
+ "AS string_agg_1 FROM table1",
+ )
+
+ def test_aggregate_order_by_multi_col(self):
+ table = Table("table1", MetaData(), Column("a", Integer), Column("b", Integer))
+ expr = func.string_agg(
+ table.c.a,
+ aggregate_order_by(
+ literal_column("','"), table.c.a, table.c.b.desc()
+ ),
+ )
+ stmt = select(expr)
+
+ self.assert_compile(
+ stmt,
+ "SELECT string_agg(table1.a, "
+ "',' ORDER BY table1.a, table1.b DESC) "
+ "AS string_agg_1 FROM table1",
+ )
+
+ def test_aggregate_order_by_no_arg(self):
+ assert_raises_message(
+ TypeError,
+ "at least one ORDER BY element is required",
+ aggregate_order_by,
+ literal_column("','"),
+ )
+
+ def test_aggregate_order_by_adapt(self):
+ table = Table("table1", MetaData(), Column("a", Integer), Column("b", Integer))
+ expr = func.array_agg(aggregate_order_by(table.c.a, table.c.b.desc()))
+ stmt = select(expr)
+
+ a1 = table.alias("foo")
+ stmt2 = util.ClauseAdapter(a1).traverse(stmt)
+ self.assert_compile(
+ stmt2,
+ "SELECT array_agg(foo.a ORDER BY foo.b DESC) AS array_agg_1 "
+ "FROM table1 AS foo",
+ )
+
class ReturnTypeTest(AssertsCompiledSQL, fixtures.TestBase):
def test_array_agg(self):
from sqlalchemy import select
from sqlalchemy import Text
from sqlalchemy import UniqueConstraint
-from sqlalchemy.dialects.postgresql import aggregate_order_by
+from sqlalchemy.sql import aggregate_order_by
+from sqlalchemy.dialects.postgresql import aggregate_order_by as pg_aggregate_order_by
from sqlalchemy.dialects.postgresql import ARRAY
from sqlalchemy.dialects.postgresql import array
from sqlalchemy.dialects.postgresql import DATERANGE
# EXPECTED_TYPE: Select[Tuple[Sequence[str]]]
reveal_type(stmt_array_agg_order_by_2)
+
+# Test backwards compatibility - both should work the same
+stmt_backwards_compat = select(
+ func.array_agg(
+ pg_aggregate_order_by(Test.ident_str, Test.id.desc(), Test.ident),
+ )
+)
+
+# EXPECTED_TYPE: Select[Tuple[Sequence[str]]]
+reveal_type(stmt_backwards_compat)