Jest bardzo prosty w obsłudze ale musimy go najpierw skonfigurować. Przykładowy plik konfiguracyjny zawiera (pgloader.conf jest domyślnym plikiem konfiguracyjnym):
[pgsql] base = pgloader host = 127.0.0.1 port = 7432 user = postgres pass = log_file = /tmp/pgloader.log log_min_messages = INFO client_min_messages = WARNING lc_messages = C pg_option_client_encoding = 'utf-8' pg_option_standard_conforming_strings = on pg_option_work_mem = 128MB copy_every = 20000 null = "" empty_string = "\ " max_parallel_sections = 4
Znaczenie parametrów:
- base - baza danych, do której będą ładowane dane
- host / post / user / pass - dane do połączenia się do bazy danych
- log_file - ścieżka do pliku logowania
- log_min_messages / client_min_messages -poziom logowania danych
- lc_messages - ustawia zmienną LC_MESSAGES dla połączenia
- pg_option_<foo> - ustawa dowolną zmienną <foo> dla połączenia
- copy_every - maksymalna ilość danych importowana przez paczkę
- null / empty_string - parametry są związane z interpretacją danych w tekście lub w plikach CSV. Zmienne odpowiednio definiują jak wartości NULL/puste stringi są reprezentowane w importowanych danych
Przykład danych:cat test_copy.csv "",2 , "\ ",3 'eeee',0 ee eee,9 eee,
Dla ustawień przedstawionych powyżej dane będą zapisane w bazie następująco:select c2,c3 from test_copy; +---------+------+ | c2 | c3 | +---------+------+ | NULL | 2 | | NULL | NULL | | | 3 | | 'eeee' | 0 | | ee eee | 9 | | eee | NULL | +---------+------+ (6 rows) Time: 0,400 ms
- max_parallel_sections - ilość paczek do załadowania w tym samym czasie
Przejdźmy dalej do ustawienia formatu plików. Ja chcę zaimportować plik CSV, a to są moje ustawienia:
[csv] table = pgloader_table format = csv filename = csv_without_header.data field_sep = , quotechar = " columns = c1, c2, c3, c4, c5, c6, c7, c8, c9Dane zostaną zapisane w tabeli pgloader_table i zostaną zaimportowane z pliku csv_witout_header.data Parametr kolumn wskazuje kolumny, w których mają zostać zapisane dane.
Uruchamiany PGLoader
W poniższym przykładzie użyłam opcji:
- T (--truncate) - wymuś czyszczenie tabeli przed załadowaniem
- s (--summary) - wypisz podumowanie
- v (--verbose) - wypisz informacje o przetrważaniu
- c (-c CONFIG, --config=CONFIG) - ścieżka do pliku konfiguracyjnego
pgloader -Tsvc pgloader.conf csv pgloader INFO Logger initialized pgloader WARNING path entry '/usr/share/python-support/pgloader/reformat' does not exists, ignored pgloader INFO Reformat path is [] pgloader INFO Will consider following sections: pgloader INFO csv csv INFO csv processing csv INFO TRUNCATE TABLE pgloader_table; pgloader INFO All threads are started, wait for them to terminate csv INFO COPY 1: 20000 rows copied in 1.651s csv INFO COPY 2: 20000 rows copied in 1.752s csv INFO COPY 3: 20000 rows copied in 1.809s csv INFO COPY 4: 20000 rows copied in 1.815s csv INFO COPY 5: 20000 rows copied in 1.736s csv INFO COPY 6: 20000 rows copied in 1.738s csv INFO COPY 7: 20000 rows copied in 1.710s csv INFO COPY 8: 20000 rows copied in 1.618s csv INFO COPY 9: 20000 rows copied in 1.611s csv INFO COPY 10: 20000 rows copied in 1.624s csv INFO COPY 11: 19173 rows copied in 1.535s csv INFO No data were rejected csv INFO 219173 rows copied in 11 commits took 18.761 seconds csv INFO No database error occured csv INFO closing current database connection csv INFO releasing csv semaphore csv INFO Announce it's over Table name | duration | size | copy rows | errors ==================================================================== csv | 18.757s | - | 219173 | 0
Jak to działa po stronie PostgreSQL?
Program dzieli dane na części (wielkość każdej części jest uzależniona od parametry copy_every), ustawia połączenie z baza danych, wykonuje zapytanie COPY:
COPY pgloader_table (KOLUMNY, ...) FROM STDOUT WITH DELIMITER ',';
i na standardowe wyście wysyła dane. Jeśli chcieli byśmy wykonać to ręcznie to odbyło by się to następująco:
127.0.0.1:7432 postgres@pgloader # COPY test_copy (c2,c3) FROM STDOUT WITH DELIMITER ','; Enter data to be copied followed by a newline. End with a backslash and a period on a line by itself. >> cos tam 1,2 >> cos tam 2,3 >> cos tam 4,4 >> cos tam 5,25 >> \. Time: 52529,504 ms 127.0.0.1:7432 postgres@pgloader # select * from test_copy; +----+-----------+----+ | id | c2 | c3 | +----+-----------+----+ | 1 | cos tam 1 | 2 | | 2 | cos tam 2 | 3 | | 3 | cos tam 4 | 4 | | 4 | cos tam 5 | 25 | +----+-----------+----+ (4 rows) Time: 0,337 ms
Do pustej tabeli test_copy importuje 4 wiersze. Dane do kolumn są oddzielone przecinkiem. Po wykonaniu komendy COPY PostgreSQL informuje nas:
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself.
Ciekawostka!
Jeśli się zastanawiacie jak to możliwe, że pgloader używa polecenia COPY w ten sposób skoro w według dokumentacji (http://www.postgresql.org/docs/9.1/static/sql-copy.html) polecenie COPY ma konstrukcje:
COPY table_name [ ( column [, ...] ) ] FROM { 'filename' | STDIN } [ [ WITH ] ( option [, ...] ) ] COPY { table_name [ ( column [, ...] ) ] | ( query ) } TO { 'filename' | STDOUT } [ [ WITH ] ( option [, ...] ) ]to zaznaczę od razu, że dozwolona jest kombinacja FROM/TO i STDIN/STDOUT (mimo iż dokumentacja na to nie wskazuję!). Aby wyjaśnić troszkę tą nieścisłość i może niedowierzanie, kieruje was do posta z listy "pgsql-hackers": Re: "COPY foo FROM STDOUT" and ecpg.
PGLoader będzie szczególnie przydatne gdy chcecie zaimportować dane a nie macie praw dostępu administratora do serwera - aby zaimportować dane z pliku przy pomocy polecenia COPY, wymagane jest przekopiowanie go na serwer. Narzędzie dodatkowo formatuje nasze dane i informuje o błędach bez przerywania importu danych poprawnych (ale opcja --pedantic wymusi zatrzymanie procesowania w razie wystąpienia warningów).
Brak komentarzy:
Prześlij komentarz