Unbekannter zurückgegebener Typ in der PostgreSQL-Abfrage


9

Die folgende Abfrage funktioniert:

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

a b
_ _
1 2
3 2

Ich konnte jedoch keinen anderen Spaltentyp verwenden, z. B 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.

Es scheint, dass im zweiten Fall der Spaltentyp als abgeleitet wird unknown, der nicht varchar(255)automatisch umgewandelt wird.

Wie kann ich das zweite Beispiel zum Laufen bringen und Spalten mit dem richtigen Typ zurückgeben, wenn möglich ohne Warnungen und ohne Änderung der ARRAY[...]Definition?

Hintergrund: Ich versuche, die Leistung großer Masseneinfügungsvorgänge mithilfe des psycopg2Python-Moduls zu verbessern , das die Verwendung mehrerer Zeilen in VALUESArgumenten nicht unterstützt . Ich bin auf das obige Beispiel gestoßen, als ich einige andere Methoden ausprobiert habe.


Ich bin mir nicht sicher, warum Sie angeben, dass psycopg2 nicht mehrere Zeilen unterstützt VALUES. Folgendes funktioniert gut für mich:cur.execute('INSERT INTO foo VALUES (%s, %s), (%s, %s), (%s, %s)', (1, 'foo', 2, 'bar', 3, 'baz'))
Dave Jones

Was ich meine ist, dass es keine beliebige Anzahl von Zeilen unterstützt, zB etwas wie cur.execute('INSERT INTO too VALUES %s', (list_of_rows,))existiert nicht.
FX

Ahh, und Sie hoffen, das Array als einen einzelnen Parameter zu ersetzen, verstehe ich.
Dave Jones

Antworten:


7

Sie können dies tun, ohne eine Warnung zu generieren, indem Sie einen Typ erstellen und die Datensätze in diesen umwandeln:

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

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

getestet auf 9.4 und 9.3 (db <> fiddle here )


7

Es ist hässlich, aber Sie können versuchen:

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

Auf diese Weise ASstimmt der in definierte Typ mit der Ausgabe von überein unnest(), die Sie in der SELECTListe an Ihre Anforderungen anpassen können.

Sie können dies in einer kleinen SQLFiddle versuchen .


1

Sollte es tun:

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

1
Dies funktioniert, aber ich konnte nicht erzwingen psycopg2, Typumwandlungen in die ARRAY[...]Definition aufzunehmen. Ist es möglich, darauf zu verzichten? Ich habe meine Frage bearbeitet, um dies widerzuspiegeln.
FX
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.