Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kcbg4-0005iG-1W for psycopg@arkaria.postgresql.org; Tue, 10 Nov 2020 21:59:48 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1kcbg2-000750-TZ for psycopg@arkaria.postgresql.org; Tue, 10 Nov 2020 21:59:46 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kcbg2-00074t-OL for psycopg@lists.postgresql.org; Tue, 10 Nov 2020 21:59:46 +0000 Received: from mail-vs1-xe31.google.com ([2607:f8b0:4864:20::e31]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1kcbg0-000232-OQ for psycopg@postgresql.org; Tue, 10 Nov 2020 21:59:46 +0000 Received: by mail-vs1-xe31.google.com with SMTP id b67so11994vsc.3 for ; Tue, 10 Nov 2020 13:59:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=8aJMtm2nzAc8EdPjUJQiwJrt5aorPIy0wQ4zik/UgVo=; b=DdvWSRM3FH4c4LlVyDw/J/bfrwhvMbf4nbHxYlhGaGex4bVro1havBs4Owyc3saeD2 suFVm5sbv6FAi0QETksBMb02Y8LLiJQlEmTypUP46zjm7vG18NHECONJ4HCklj+H6yS0 7qjDQLIxC/xXv4NeSo2zSohNfvdmPXeDY3NhapDfY57cUSJ/7CuUEf0aVH9j+/VnTQ4Z 40wlHvH5+m5OnBGSmfsclTs1lRzSpV9JQQ9QpfKzyrqReicdwxHzYTYLr3lhZ4r48eeg ijOTMLbi2ETElp4H0OQmkfyUVb5XwhHPawHpTIgCy8JjD7IMGF6iBchbrzg4R9NMz02k bLXA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=8aJMtm2nzAc8EdPjUJQiwJrt5aorPIy0wQ4zik/UgVo=; b=oeuYSxW/5QVTvkknPPuAsBfvn06IH0Yw1VFyCkKwI8LlC4zxLNH+Q7I/Cms/6HQJNX YhuK3Tf1O70kLxlCjvuz2DZ68q0Cvi255RU4o+c7VScFvdmnUWXwKao50Y6An87UDhCt +bkXKJOnUMr2QC/nln9rDMylkchNE7K9EsMx9gt2OgTbrAeUlc7bIbSmD2S0+05Pn0bN eUY4QJuGKA4d/Sns6EiwFKwgClsXQMrof4W9is7uYGddyjhJbliu9JT6c4Ep03KtGWbN 59BomnYw9aEZas979u/Nv4058R1SZ4gPm3u7DOGTTAUuDANiDx/pQhl107bdlhS+7MC0 sfrA== X-Gm-Message-State: AOAM531KBLkzkZODsTg2pEGc0B/bZvXA0xgHV4JOoW6vjc4hnUuJIe5W nYxRie2YLqDFhz9zFfdRDNW1XCWnlHbkwkwyMheXcCUlz+CbsA== X-Google-Smtp-Source: ABdhPJwxm5VhQ/HDntRx52kiT8ulyR7R6Jl9dJDHix/9RmYkrL1OBs+W/IiSl4dYv/bQuQhuAyT8L2h+WP28HSnkZMY= X-Received: by 2002:a67:fac4:: with SMTP id g4mr13592447vsq.9.1605045582545; Tue, 10 Nov 2020 13:59:42 -0800 (PST) MIME-Version: 1.0 From: Vladimir Ryabtsev Date: Tue, 10 Nov 2020 13:59:31 -0800 Message-ID: Subject: Using composite types in psycopg3 To: psycopg@postgresql.org Content-Type: multipart/alternative; boundary="000000000000cbc78805b3c7cbc6" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --000000000000cbc78805b3c7cbc6 Content-Type: text/plain; charset="UTF-8" Hello, I have tried psycopg3 very briefly and I have a question. I have a couple of use cases in systems I currently work with that prevented (or seriously limited) usage of psycopg2, so I had to use other drivers. This generally relates to accessing composite types that you can construct on-the-fly in SQL queries. Consider the following example: ''' import psycopg2 def get_query(fpath): with open(fpath, 'rt') as f: return f.read() def main(): conn = psycopg2.connect('postgres://user:password@host/db') cur = conn.cursor() cur.execute(get_query('query.sql')) result = cur.fetchone()[0] print(type(result), result) cur.close() conn.close() if __name__ == '__main__': main() ''' Where query.sql is: ''' with test as ( select 1 as id, 'one' val union all select 1, 'one more' union all select 2, 'two' ) select array( select (id, array_agg(val)) from test group by id ) ''' psycopg2 returns the 'result' as a basic string, while in asyncpg and py-postgresql I have structured data (roughly 'List[Tuple[int, List[str]]]'). I tried the same in psycopg3 and it is little bit better, but not entirely: it shows the outer list, the tuples inside it, but the innermost list is still represented as a basic string: '{one,"one more"}'. Is it something you are still working on? Any workarounds? Vladimir --000000000000cbc78805b3c7cbc6 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hello,

I have tried psycopg3 very brief= ly and I have a question.

I have a couple=C2=A0of = use cases in systems I currently work with
that prevented (or ser= iously limited) usage of psycopg2, so
I had to use other drivers.= This generally relates to accessing
composite types that you can= construct on-the-fly in SQL queries.
Consider the following exam= ple:

'''
import psycopg2
=
def get_query(fpath):
=C2=A0 =C2=A0 with open(fpath, 'rt') a= s f:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return f.read()

def main():
= =C2=A0 =C2=A0 conn =3D psycopg2.connect('postgres://user:password@host/= db')
=C2=A0 =C2=A0 cur =3D conn.cursor()
=C2=A0 =C2=A0 cur.execut= e(get_query('query.sql'))
=C2=A0 =C2=A0 result =3D cur.fetchone(= )[0]
=C2=A0 =C2=A0 print(type(result), result)
=C2=A0 =C2=A0 cur.clos= e()
=C2=A0 =C2=A0 conn.close()

if __name__ =3D=3D '__main__&#= 39;:
=C2=A0 =C2=A0 main()
'''

Where query.sql is:

'''
=
with test as (
=C2=A0 =C2=A0 select 1 as id, 'one' val
= =C2=A0 =C2=A0 union all
=C2=A0 =C2=A0 select 1, 'one more'
= =C2=A0 =C2=A0 union all
=C2=A0 =C2=A0 select 2, 'two'
)
s= elect array(
=C2=A0 =C2=A0 select (id, array_agg(val))
=C2=A0 =C2=A0= from test
=C2=A0 =C2=A0 group by id
)
'''=

psycopg2 returns the 'result' as a basic = string, while
in asyncpg and py-postgresql I have structured data=
(roughly 'List[Tuple[int, List[str]]]').

<= /div>
I tried the same in psycopg3 and it is little bit better, but
not entirely: it shows the outer list, the tuples inside it,
but the innermost list is still represented as a basic string:
'{one,"one more"}'.

Is it s= omething you are still working on? Any workarounds?

Vladimir
--000000000000cbc78805b3c7cbc6--