Tipo restituito sconosciuto nella query PostgreSQL


9

La seguente query funziona:

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

a b
_ _
1 2
3 2

Tuttavia, non sono stato in grado di utilizzare un diverso tipo di colonna come 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.

Sembra che, nel secondo caso, venga inferito il tipo di colonna unknown, che non viene varchar(255)automaticamente castato .

Come faccio a far funzionare il secondo esempio e restituire colonne con il tipo giusto, se possibile senza avvisi e senza modificare la ARRAY[...]definizione?

Contesto: sto cercando di migliorare le prestazioni di operazioni di inserimento di grandi quantità utilizzando il psycopg2modulo Python, che non supporta l'utilizzo di più righe negli VALUESargomenti. Mi sono imbattuto nell'esempio sopra mentre provavo altri metodi.


Non sono sicuro del motivo per cui affermi che psycopg2 non supporta più righe in VALUES. Per me funziona perfettamente:cur.execute('INSERT INTO foo VALUES (%s, %s), (%s, %s), (%s, %s)', (1, 'foo', 2, 'bar', 3, 'baz'))
Dave Jones,

Ciò che intendo è che non supporta un numero arbitrario di righe, ad esempio qualcosa di simile cur.execute('INSERT INTO too VALUES %s', (list_of_rows,))non esiste.
FX

Ahh, e speri di sostituire l'array come un singolo parametro, vedo.
Dave Jones,

Risposte:


7

Puoi farlo senza generare un avviso creando un tipo e trasmettendo i record su di esso:

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

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

testato su 9.4 e 9.3 (db <> violino qui )


7

È brutto, ma puoi provare:

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

In questo modo il tipo definito AScorrisponde all'output di unnest(), che è possibile trasmettere alle proprie esigenze SELECTnell'elenco.

Puoi provarlo in un piccolo SQLFiddle .


1

Dovrebbe farlo:

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

1
Funziona, tuttavia non sono stato in grado di forzare psycopg2l'inclusione dei cast di tipi all'interno della ARRAY[...]definizione. È possibile farlo senza? Ho modificato la mia domanda per riflettere ciò.
FX
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.