Неизвестный возвращаемый тип в запросе 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аргументах. Я наткнулся на приведенный выше пример, пробуя другие методы.


Я не уверен, почему вы заявляете, что 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 (дб <> скрипка здесь )


7

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

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

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

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


1

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

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

1
Это работает, однако я не смог принудительно psycopg2включить приведение типов в ARRAY[...]определение. Можно ли обойтись без? Я отредактировал свой вопрос, чтобы отразить это.
FX
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.