Tipo devuelto desconocido en la consulta PostgreSQL

9

La siguiente consulta funciona:

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

a b
_ _
1 2
3 2

Sin embargo, no pude usar un tipo de columna diferente como 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.

Parece que, en el segundo caso, el tipo de columna se infiere como unknown, que no se convierte varchar(255)automáticamente.

¿Cómo hago para que el segundo ejemplo funcione y devuelva columnas con el tipo correcto, si es posible sin advertencias y sin modificar la ARRAY[...]definición?

Antecedentes: estoy tratando de mejorar el rendimiento de las operaciones de inserción masiva grandes utilizando el psycopg2módulo Python, que no admite el uso de varias filas en los VALUESargumentos. Me topé con el ejemplo anterior mientras probaba algunos otros métodos.

FX
fuente
No estoy seguro de por qué afirmas que psycopg2 no admite múltiples filas VALUES. Lo siguiente funciona bien para mí:cur.execute('INSERT INTO foo VALUES (%s, %s), (%s, %s), (%s, %s)', (1, 'foo', 2, 'bar', 3, 'baz'))
Dave Jones
Lo que quiero decir es que no admite un número arbitrario de filas, por ejemplo, algo como cur.execute('INSERT INTO too VALUES %s', (list_of_rows,))no existe.
FX
Ahh, y espero sustituir la matriz como un solo parámetro, ya veo.
Dave Jones

Respuestas:

7

Puede hacerlo sin generar una advertencia creando un tipo y transmitiéndole los registros:

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

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

probado en 9.4 y 9.3 (db <> violín aquí )

Jack dice que intente topanswers.xyz
fuente
7

Es feo, pero puedes probar:

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

De esta forma, el tipo definido en AScoincide con la salida de unnest(), que puede convertir a sus necesidades en la SELECTlista.

Puede probar esto en un pequeño SQLFiddle .

dezso
fuente
1

Deberías hacerlo:

SELECT a, b
FROM unnest(ARRAY[(1,varchar 'hello'), (3,varchar 'world')])
AS t(a integer, b varchar(255));
JoseTeixeira
fuente
1
Esto funciona, sin embargo, no pude forzar la psycopg2inclusión de los tipos dentro de la ARRAY[...]definición. ¿Es posible hacerlo sin? Edité mi pregunta para reflejar eso.
FX