2011-08-13 10 views
7

Wyeksportowałem niektóre dane z mojej bazy danych w formie JSON, która jest w zasadzie tylko 1 [list] z wiązką (900K) z {obiektów} wewnątrz niej.Podziel 95MB JSON na mniejsze porcje?

Próbuję teraz zaimportować go na mój serwer produkcyjny, ale mam tani serwer WWW. Nie podoba im się to, gdy jem wszystkie swoje zasoby przez 10 minut.

W jaki sposób mogę podzielić ten plik na mniejsze części, aby móc go importować kawałek po kawałku?


Edit: Faktycznie, jest to baza danych PostgreSQL. Jestem otwarty na inne sugestie dotyczące eksportu wszystkich danych w porcjach. Mam zainstalowany phpPgAdmin na moim serwerze, który prawdopodobnie może akceptować formaty CSV, Tabbed i XML.


musiałem naprawić skrypt phihag za:

import json 
with open('fixtures/PostalCodes.json','r') as infile: 
    o = json.load(infile) 
    chunkSize = 50000 
    for i in xrange(0, len(o), chunkSize): 
    with open('fixtures/postalcodes_' + ('%02d' % (i//chunkSize)) + '.json','w') as outfile: 
     json.dump(o[i:i+chunkSize], outfile) 

wysypisko:

pg_dump -U username -t table database > filename 

przywrócić:

psql -U username < filename 

(I don” t Wiesz, co do cholery robi pg_restore, ale daje mi to błędy)

Samouczki na ten temat wygodnie zostawiają tę informację, szczególnie. opcja -U, która jest prawdopodobnie konieczna w większości przypadków. Tak, strony man wyjaśniają to, ale zawsze jest ciężko przesiać przez 50 opcji, których nie obchodzi.


Skończyłem z sugestią Kenny'ego ... chociaż nadal był to poważny problem. Musiałem zrzucić tabelę do pliku, skompresować, przesłać, wyodrębnić, a następnie próbowałem go zaimportować, ale dane nieco różniły się od produkcji i brakowało obcych kluczy (kody pocztowe są dołączone do miast). Oczywiście, nie mogłem po prostu zaimportować nowych miast, ponieważ wtedy rzucił duplikat błędu klucza, zamiast go cicho ignorować, co byłoby miłe. Musiałem więc opróżnić ten stół, powtórzyć proces dla miast, tylko po to, aby zdać sobie sprawę, że coś innego jest związane z miastami, więc musiałem opróżnić ten stół. Wróciłem do miast, wreszcie mogłem zaimportować moje kody pocztowe. Do tej pory zniszczyłem połowę mojej bazy danych, ponieważ wszystko jest powiązane ze wszystkim i musiałem odtworzyć wszystkie wpisy. Śliczny. Dobrze, że jeszcze nie uruchomiłem strony. Również "opróżnianie" lub obcinanie tabeli nie wydaje się resetować sekwencji/auto-deklinacji, które chciałbym, ponieważ jest kilka magicznych wpisów Chcę mieć ID 1. Więc ... musiałem usunąć lub zresetować te też (nie wiem jak), więc ręcznie edytowałem PKs dla tych z powrotem do 1.

Wpadłbym na podobne problemy z rozwiązaniem phihag, a ja musiałbym importować 17 plików jeden na czas, chyba że napisałem inny skrypt importu, aby dopasować skrypt eksportu. Mimo że odpowiedział na moje pytanie dosłownie, dzięki.

Odpowiedz

1

Zakładając, masz możliwość, aby wrócić i ponownie wyeksportować dane ...:

pg_dump - wypakuj bazę danych PostgreSQL do pliku skryptu lub innego pliku archiwum.

pg_restore - przywracanie bazy danych PostgreSQL z pliku archiwum utworzonego przez pg_dump.

Jeśli to nie pomoże, może być przydatne wiedzieć, co zamierzasz zrobić z danymi wyjściowymi, aby inna sugestia mogła trafić w znak.

+0

pg_dump byłoby w porządku .... ale przywracanie prawdopodobnie nadal zużywa zbyt wiele zasobów, jeśli nie jest w porcjach. Wszystko, co robię z danymi wyjściowymi, to importowanie go na mój serwer produkcyjny. – mpen

+0

Jestem teraz w celu odgadnięcia terytorium, ale myślałem, że wysokie wykorzystanie zasobów w metodzie JSON będzie miało związek z analizą JSON. Ale jak mówię, to jest totalne przypuszczenie. Próbowałem użyć metody pg_dump i pg_restore, aby zobaczyć, co się stało (oczywiście podczas oglądania zasobów;)). – Kenny

+0

Wygląda na to (prawdopodobnie jest już oczywiste, że wcześniej nie korzystałem z PostgreS): - tylko -data- Zrzuć tylko dane, a nie schemat (definicje danych). – Kenny

7

W Pythonie:

import json 
with open('file.json') as infile: 
    o = json.load(infile) 
    chunkSize = 1000 
    for i in xrange(0, len(o), chunkSize): 
    with open('file_' + str(i//chunkSize) + '.json', 'w') as outfile: 
     json.dump(o[i:i+chunkSize], outfile) 
+0

Dostaję 'AttributeError:„str”obiektu nie ma atrybutu„__exit __”' na „z” linii. Nvm, wymyśliłem to. Wielkie dzięki! – mpen

+0

@ Mark oops, zapomniałem 'otwartego'. Naprawiony. – phihag

2

Odwróciłem phihag i pracą Marka w tiny script (gist)

również przytoczone poniżej:

#!/usr/bin/env python 
# based on http://stackoverflow.com/questions/7052947/split-95mb-json-array-into-smaller-chunks 
# usage: python json-split filename.json 
# produces multiple filename_0.json of 1.49 MB size 

import json 
import sys 

with open(sys.argv[1],'r') as infile: 
    o = json.load(infile) 
    chunkSize = 4550 
    for i in xrange(0, len(o), chunkSize): 
     with open(sys.argv[1] + '_' + str(i//chunkSize) + '.json', 'w') as outfile: 
      json.dump(o[i:i+chunkSize], outfile) 
1

Wiem, że to pytanie jest z jakiś czas temu, ale myślę, że to nowe rozwiązanie jest bezproblemowe.

Można użyć pandas 0.21.0, który obsługuje parametr porcji jako część read_json. Można załadować jeden kawałek na raz i zapisać json:

import pandas as pd 
chunks = pd.read_json('file.json', lines=True, chunksize = 20) 
for i, c in enumerate(chunks): 
    c.to_json('chunk_{}.json'.format(i)) 
Powiązane problemy