]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Improve PG reflection compat.
authorFederico Caselli <cfederico87@gmail.com>
Thu, 25 May 2023 22:17:40 +0000 (00:17 +0200)
committerFederico Caselli <cfederico87@gmail.com>
Thu, 25 May 2023 22:17:40 +0000 (00:17 +0200)
Cast ``NAME`` columns to ``TEXT`` when using ``ARRAY_AGG`` in PostgreSQL
reflection. This seems to improve compatibility with some PostgreSQL
derivatives that may not support aggregations on the ``NAME`` type.

Fixes: #9838
Change-Id: I88e12f7b6aad6cf123961d169f90e29760e953a8

doc/build/changelog/unreleased_20/9838.rst [new file with mode: 0644]
lib/sqlalchemy/dialects/postgresql/base.py

diff --git a/doc/build/changelog/unreleased_20/9838.rst b/doc/build/changelog/unreleased_20/9838.rst
new file mode 100644 (file)
index 0000000..9f7a7d1
--- /dev/null
@@ -0,0 +1,7 @@
+.. change::
+    :tags: usecase, postgresql, reflection
+    :tickets: 9838
+
+    Cast ``NAME`` columns to ``TEXT`` when using ``ARRAY_AGG`` in PostgreSQL
+    reflection. This seems to improve compatibility with some PostgreSQL
+    derivatives that may not support aggregations on the ``NAME`` type.
index 43d57fc38dfaf1564e0a8c1299cd0bd5d091f21b..8ac04d6548f2439a750833b93e5af20e519dd0d0 100644 (file)
@@ -3796,7 +3796,11 @@ class PGDialect(default.DefaultDialect):
             select(
                 attr_sq.c.conrelid,
                 sql.func.array_agg(
-                    aggregate_order_by(attr_sq.c.attname, attr_sq.c.ord)
+                    # NOTE: cast since some postgresql derivatives may
+                    # not support array_agg on the name type
+                    aggregate_order_by(
+                        attr_sq.c.attname.cast(TEXT), attr_sq.c.ord
+                    )
                 ).label("cols"),
                 attr_sq.c.conname,
                 sql.func.min(attr_sq.c.description).label("description"),
@@ -4109,8 +4113,8 @@ class PGDialect(default.DefaultDialect):
                     ),
                     # NOTE: need to cast this since attname is of type "name"
                     # that's limited to 63 bytes, while pg_get_indexdef
-                    # returns "text" so it may get cut
-                    else_=sql.cast(pg_catalog.pg_attribute.c.attname, TEXT()),
+                    # returns "text" so its output may get cut
+                    else_=pg_catalog.pg_attribute.c.attname.cast(TEXT),
                 ).label("element"),
                 (idx_sq.c.attnum == 0).label("is_expr"),
             )
@@ -4546,7 +4550,9 @@ class PGDialect(default.DefaultDialect):
                 pg_catalog.pg_enum.c.enumtypid,
                 sql.func.array_agg(
                     aggregate_order_by(
-                        pg_catalog.pg_enum.c.enumlabel,
+                        # NOTE: cast since some postgresql derivatives may
+                        # not support array_agg on the name type
+                        pg_catalog.pg_enum.c.enumlabel.cast(TEXT),
                         pg_catalog.pg_enum.c.enumsortorder,
                     )
                 ).label("labels"),
@@ -4609,9 +4615,11 @@ class PGDialect(default.DefaultDialect):
                         pg_catalog.pg_constraint.c.oid, True
                     )
                 ).label("condefs"),
-                sql.func.array_agg(pg_catalog.pg_constraint.c.conname).label(
-                    "connames"
-                ),
+                sql.func.array_agg(
+                    # NOTE: cast since some postgresql derivatives may
+                    # not support array_agg on the name type
+                    pg_catalog.pg_constraint.c.conname.cast(TEXT)
+                ).label("connames"),
             )
             # The domain this constraint is on; zero if not a domain constraint
             .where(pg_catalog.pg_constraint.c.contypid != 0)