PostgreSQL Bulk insert powiązanych tabel

0

Hej,
Potrzebuję wrzucić sporą ilość danych do powiązanych ze sobą tabel, ale przyznam szczerze nie wiem jak to zrobić wydajnie.
Mam dwie tablice NumbersTab(Id, Number) i TittlesTab (Id, Tittle, NumbersTabId).
Obecnie wgrywam dane wykorzystując dwa inserty, najpierw

Insert into  NumbersTab(Number) values
(111111),
(222222),
(333333),
...

następnie kolejny z podzapytaniem

Insert into  TittlesTab(Tittle, NumbersTabId) values
('Title', (Select Id from NumbersTab where Number = 111111)),
('Title', (Select Id from NumbersTab where Number = 222222)),
('Title', (Select Id from NumbersTab where Number = 333333)),
...

Id są autoiterowane, Number jest częścią wspólną dzięki któremu wiem jaki tytuł odpowiada jakiemu numerowi z tabeli NumbersTab.
Zasadniczo takie rozwiązanie się sprawdza, ale jest bardzo niewydajne, pgAdmin wywala błąd przy >4000 rekordów, wiec muszę dzielić rekordy, co jest "upierdliwe".

Normalnie stworzyłbym sobie aplikację, która wrzucała by mi te rekordy do bazy przy pomocy jakiejś buiblioteki do bulk insertowania, ale wymogiem jest skrypt :/.

Wiem, że postgreSQL udostępnia coś takiego jak funkcja COPY, ale nigdzie nie znalazłem implementacji z powiązanymi tabelami.
Będę wdzięczny za wszelkie porady i pomoc przy rozwiązaniu problemu.

2

Jeżeli Number jest unikalny, to może zastąpić id, i nie musisz robić podzapytania przy wstawianiu do drugiej tabeli.

Co do COPY pozwala kopiować dane np. z CSV.

Możesz zrobić tak:

  1. najpierw COPY do NumbersTab z CSV
  2. następnie z NumbersTab export do drugiego pliku CSV też przez COPY: COPY (SELECT * FROM ...) TO 'filename.csv' (FORMAT csv);
  3. z tego drugiego pliku CSV (filename.csv) gdzie masz juz id, COPY do drugiej tabeli
0
TomRZ napisał(a):

Jeżeli Number jest unikalny, to może zastąpić id, i nie musisz robić podzapytania przy wstawianiu do drugiej tabeli.

Co do COPY pozwala kopiować dane np. z CSV.

Możesz zrobić tak:

  1. najpierw COPY do NumbersTab z CSV
  2. następnie z NumbersTab export do drugiego pliku CSV też przez COPY: COPY (SELECT * FROM ...) TO 'filename.csv' (FORMAT csv);
  3. z tego drugiego pliku CSV (filename.csv) gdzie masz juz id, COPY do drugiej tabeli

Dzięki za odpowiedź :)
Number jest unikatowy, ale niestety nie może on zastąpić Id (wymóg projektowy, numer może zostać zmieniony przez użytkownika na inny), o tym pomyślałem w pierwszej kolejności.
Sposób z COPY wygląda w sumie ok, sprawdzę jutro, dzięki :)

2

Za pomocą COPY tego nie ogarniesz. Chyba, że zasymulujesz backup i załadujesz z instiejącej bazy z CSV.
Ale może to zrobić normalnymi insertami wykorzystując RETURNING
Przykład tu: (jakiś taki podstawowy zrobiłem, dla zobraznwania)
https://www.db-fiddle.com/f/w57HryDk7mr11ET1GCFWg5/0

0

Czy masz jakieś ograniczenia co do tego ładowania danych? np. ładowane tylko inicjalnie/migrowane, czy może być to realizowane po stronie serwera bazodanowego czy musi po stronie klienta?

0
TomRZ napisał(a):

Jeżeli Number jest unikalny, to może zastąpić id, i nie musisz robić podzapytania przy wstawianiu do drugiej tabeli.

Co do COPY pozwala kopiować dane np. z CSV.

Możesz zrobić tak:

  1. najpierw COPY do NumbersTab z CSV
  2. następnie z NumbersTab export do drugiego pliku CSV też przez COPY: COPY (SELECT * FROM ...) TO 'filename.csv' (FORMAT csv);
  3. z tego drugiego pliku CSV (filename.csv) gdzie masz juz id, COPY do drugiej tabeli

Przetestowałem i niby ok, ale tak jak przypuszczałem przypisuje mi na sztywno Id NumbersTab w drugiej tabelce :/ niestety jest to baza na której pracuje klient i może dodać kolejny element, co będzie skutkowało rozjazdem z danymi z csv, niestety ten warunek sprawdzania id po numbers musi być ad hoc.

1 użytkowników online, w tym zalogowanych: 0, gości: 1