From: Federico Caselli Date: Thu, 25 May 2023 22:17:40 +0000 (+0200) Subject: Improve PG reflection compat. X-Git-Tag: rel_2_0_16~25^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0ea59dcf455052c1f307cfbfa18b0ddb4cc95cd0;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Improve PG reflection compat. 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 --- diff --git a/doc/build/changelog/unreleased_20/9838.rst b/doc/build/changelog/unreleased_20/9838.rst new file mode 100644 index 0000000000..9f7a7d18c1 --- /dev/null +++ b/doc/build/changelog/unreleased_20/9838.rst @@ -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. diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py index 43d57fc38d..8ac04d6548 100644 --- a/lib/sqlalchemy/dialects/postgresql/base.py +++ b/lib/sqlalchemy/dialects/postgresql/base.py @@ -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)