PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Wie ändere ich eine Tabellen-ID von seriell in Identität?

BEGIN;
ALTER TABLE public.client ALTER clientid DROP DEFAULT; -- drop default

DROP SEQUENCE public.client_clientid_seq;              -- drop owned sequence

ALTER TABLE public.client
-- ALTER clientid SET DATA TYPE int,                   -- not needed: already int
   ALTER clientid ADD GENERATED ALWAYS AS IDENTITY (RESTART 108);
COMMIT;

Es gibt zwei Variablen:

  • der tatsächliche Name der angehängten SEQUENCE . Ich habe oben den Standardnamen verwendet, aber der Name kann abweichen.
  • der aktuelle Maximalwert in client.clientid . Muss nicht 107 sein, nur weil es derzeit 107 Zeilen gibt.

Diese Abfrage erhält beides:

SELECT pg_get_serial_sequence('client', 'clientid'), max(clientid) FROM client;

Eine serial Spalte ist eine integer Spalte, die besitzt eine dedizierte Sequenz und hat einen Standardsatz, um daraus zu zeichnen (wie aus der von Ihnen geposteten Tabellendefinition ersichtlich). Um daraus eine einfache integer zu machen , löschen Sie den Standardwert und löschen Sie dann die Sequenz.

Konvertieren der Spalte in eine IDENTITY fügt eine eigene Sequenz hinzu. Sie müssen lösche die alte eigene Sequenz (oder zumindest die Eigentümerschaft, die mit dem Löschen der Sequenz stirbt). Andernfalls erhalten Sie Fehler wie:

Wie kopiere ich Struktur und Inhalt einer Tabelle, aber mit separater Reihenfolge?

Konvertieren Sie dann die einfache integer Spalte zu einer IDENTITY Spalte und starten Sie mit dem aktuellen Maximum plus 1 neu . Sie müssen Setzen Sie den aktuellen Wert der neuen internen Sequenz, um eindeutige Verletzungen zu vermeiden.

Fassen Sie alles in einer einzigen Transaktion zusammen, damit Sie die Migration nicht auf halbem Weg vermasseln. Alle diese DDL-Befehle sind transaktional in Postgres, können zurückgesetzt werden, bis sie festgeschrieben werden, und sind nur für andere Transaktionen sichtbar, die danach beginnen.

Ihre Spalte war vorher PK und bleibt PK. Dies ist orthogonal zur Änderung.

Peter Eisentraut, der Hauptautor der (neu in Postgres 10) IDENTITY Funktion, stellte auch eine Funktion upgrade_serial_to_identity() bereit um bestehende serial umzuwandeln Säulen. Es verwendet die vorhandene Sequenz wieder und aktualisiert stattdessen Systemkataloge direkt - was Sie nicht selbst tun sollten, es sei denn, Sie wissen genau, was Sie tun. Es deckt auch exotische Eckfälle ab. Probieren Sie es aus (Kapitel "Upgrade"):

Die Funktion funktioniert jedoch nicht bei den meisten gehosteten Diensten, die keine direkte Manipulation von Systemkatalogen zulassen. Dann kehren Sie zu den DDL-Befehlen zurück, wie oben beschrieben.

Verwandte: