Muszę przeprowadzić migrację dużej ilości istniejących danych w DB PostgreS po zmianie schematu.Wstawianie danych i ustawianie kluczy obcych za pomocą Postgreatora
W starym schemacie atrybut kraju będzie przechowywany w tabeli użytkowników. Teraz atrybut kraj został przeniesiony do osobnej tabeli adres:
users:
country # OLD
address_id # NEW [1:1 relation]
addresses:
id
country
Schemat jest rzeczywiście bardziej skomplikowane i adres zawiera więcej niż tylko kraju. Dlatego każdy użytkownik musi mieć swój własny adres (relacja 1: 1).
Podczas migracji danych, Mam problemy ustawienie kluczy obcych w tabeli użytkowników po włożeniu adresy:
INSERT INTO addresses (country)
SELECT country FROM users WHERE address_id IS NULL
RETURNING id;
jaki sposób propagować identyfikatory wstawionych wierszy i ustawić klucz obcy referencje w tabeli użytkowników?
Jedynym rozwiązaniem mogłem wymyślić do tej pory jest stworzenie tymczasowej kolumny user_id w tabeli adresy i następnie aktualizowanie się address_id:
UPDATE users SET address_id = a.id FROM addresses AS a
WHERE users.id = a.user_id;
Jednak okazało się to być bardzo powolna (mimo za pomocą indeksów na obu users.id i addresses.user_id).
Tabela użytkowników zawiera około 3 miliony wierszy z 300 tys. Brakujących adresów.
Czy istnieje inny sposób wstawiania danych pochodnych do jednej tabeli i ustawiania odwołania do klucza obcego do wstawionych danych w drugiej (bez zmiany samego schematu)?
Używam Postgres 8.3.14.
Dzięki
Mam teraz rozwiązać problem poprzez migrację danych ze skryptu Python/SQLAlchemy. Okazało się to znacznie łatwiejsze (dla mnie) niż próba tego samego z SQL. Mimo to byłbym zainteresowany, gdyby ktokolwiek znał sposób przetwarzania wyniku RETURNING instrukcji INSERT w Postgres SQL.
To jest stare i rozwiązałeś to. Ale stosunek 1: 1 nie ma sensu w tym przypadku. Nie powinieneś zamiast tego tworzyć tabeli krajów? –
Adres faktycznie zawiera ulicę, miasto, kod pocztowy, ... i kraj dla każdego użytkownika. Uprościłem to, aby było bardziej czytelne. – Pankrat
Kraj, kod pocztowy, miasto, hrabstwo itd. Będą miały swoje własne tabele. To pozostawia ulicę, numer itd. Wciąż nie ma miejsca w osobnej tabeli dla tych, o ile dla każdego użytkownika nie jest możliwy więcej niż jeden adres. –