Type retourné inconnu dans la requête PostgreSQL

9

La requête suivante fonctionne:

SELECT a, b
FROM unnest(ARRAY[(1,2), (3,4)])
AS t(a integer, b integer);

a b
_ _
1 2
3 2

Cependant, je n'ai pas pu utiliser un type de colonne différent tel que varchar(255):

SELECT a, b
FROM unnest(ARRAY[(1,'hello'), (3,'world')])
AS t(a integer, b varchar(255));

ERROR:  42804: function return row and query-specified return row do not match
DETAIL:  Returned type unkown at ordinal position 2, but query expects text.

Il semble que, dans le deuxième cas, le type de colonne est déduit comme unknown, qui n'est pas converti varchar(255)automatiquement.

Comment faire fonctionner le deuxième exemple et renvoyer des colonnes avec le bon type, si possible sans avertissements et sans modifier la ARRAY[...]définition?

Contexte: J'essaie d'améliorer les performances des opérations d'insertion en bloc volumineuses à l'aide du psycopg2module Python, qui ne prend pas en charge l'utilisation de plusieurs lignes dans les VALUESarguments. Je suis tombé sur l'exemple ci-dessus en essayant d'autres méthodes.

FX
la source
Je ne sais pas pourquoi vous déclarez que psycopg2 ne prend pas en charge plusieurs lignes VALUES. Les choses suivantes fonctionnent très bien pour moi:cur.execute('INSERT INTO foo VALUES (%s, %s), (%s, %s), (%s, %s)', (1, 'foo', 2, 'bar', 3, 'baz'))
Dave Jones
Ce que je veux dire, c'est qu'il ne prend pas en charge un nombre arbitraire de lignes, par exemple quelque chose comme cur.execute('INSERT INTO too VALUES %s', (list_of_rows,))n'existe pas.
FX
Ahh, et vous espérez remplacer le tableau en tant que paramètre unique, je vois.
Dave Jones

Réponses:

7

Vous pouvez le faire sans générer d'avertissement en créant un type et en y castant les enregistrements:

create type t as (a integer, b varchar(255));

select * from unnest(array[(1,'hello'), (3,'world')]::t[]);
┌───┬───────┐
 a    b   
├───┼───────┤
 1  hello 
 3  world 
└───┴───────┘

testé en 9.4 et 9.3 (db <> violon ici )

Jack dit d'essayer topanswers.xyz
la source
7

C'est moche, mais vous pouvez essayer:

SELECT a, b::text
FROM unnest(ARRAY[(1,'hello'), (3,'world')])
AS t(a integer, b unknown);

De cette façon, le type défini dans AScorrespond à la sortie de unnest(), que vous pouvez caster selon vos besoins dans la SELECTliste.

Vous pouvez essayer ceci dans un petit SQLFiddle .

dezso
la source
1

Devrait le faire:

SELECT a, b
FROM unnest(ARRAY[(1,varchar 'hello'), (3,varchar 'world')])
AS t(a integer, b varchar(255));
JoseTeixeira
la source
1
Cela fonctionne, mais je n'ai pas pu forcer l' psycopg2inclusion de transtypages de type dans la ARRAY[...]définition. Est-il possible de s'en passer? J'ai modifié ma question pour refléter cela.
FX