Неизвестный возвращаемый тип в запросе PostgreSQL

9

Следующий запрос работает:

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

a b
_ _
1 2
3 2

Однако я не смог использовать другой тип столбца, такой как 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.

Похоже, что во втором случае тип столбца выводится как unknown, который не приводится varchar(255)автоматически.

Как заставить второй пример работать и возвращать столбцы с правильным типом, если это возможно без предупреждений и без изменения ARRAY[...]определения?

Предыстория: я пытаюсь улучшить производительность больших операций массовой вставки с помощью psycopg2модуля Python, который не поддерживает использование нескольких строк в VALUESаргументах. Я наткнулся на приведенный выше пример, пробуя другие методы.

FX
источник
Я не уверен, почему вы заявляете, что psycopg2 не поддерживает несколько строк в VALUES. Следующее прекрасно работает для меня:cur.execute('INSERT INTO foo VALUES (%s, %s), (%s, %s), (%s, %s)', (1, 'foo', 2, 'bar', 3, 'baz'))
Дейв Джонс
Я имею в виду, что он не поддерживает произвольное количество строк, например, что-то вроде cur.execute('INSERT INTO too VALUES %s', (list_of_rows,))не существует.
FX
Ааа, и вы надеетесь заменить массив как один параметр, я вижу.
Дейв Джонс

Ответы:

7

Вы можете сделать это без генерации предупреждения, создав тип и приведя к нему записи:

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

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

протестировано на 9.4 и 9.3 (дб <> скрипка здесь )

Джек говорит, попробуйте topanswers.xyz
источник
7

Это некрасиво, но вы можете попробовать:

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

Таким образом, тип, определенный в, ASсовпадает с выводом unnest(), который вы можете привести в соответствии со своими потребностями в SELECTсписке.

Вы можете попробовать это в небольшом SQLFiddle .

Dezso
источник
1

Должен сделать это:

SELECT a, b
FROM unnest(ARRAY[(1,varchar 'hello'), (3,varchar 'world')])
AS t(a integer, b varchar(255));
JoseTeixeira
источник
1
Это работает, однако я не смог принудительно psycopg2включить приведение типов в ARRAY[...]определение. Можно ли обойтись без? Я отредактировал свой вопрос, чтобы отразить это.
FX