2016-09-14 19 views
5

Muszę dołączyć do wszystkich tabel PostgreSQL i przekonwertować je w słowniku Python. W bazie danych znajduje się 72 tablice. Łączna liczba kolumn jest większa niż .Dołącz do wszystkich tabel PostgreSQL i utwórz słownik w języku Python

Napisałem prosty skrypt w języku Python, który łączy kilka tabel, ale nie dołącza do nich wszystkich z powodu the memory error. Cała pamięć jest zajęta podczas wykonywania skryptu. I uruchamiam skrypt na nowym wirtualnym serwerze z pamięcią RAM i 8 procesorami. Zawodzi podczas wykonywania funkcji lambda.

W jaki sposób można poprawić poniższy kod, aby wykonać wszystkie tabele?

from sqlalchemy import create_engine 
import pandas as pd 

auth = 'user:pass' 
engine = create_engine('postgresql://' + auth + '@host.com:5432/db') 

sql_tables = ['table0', 'table1', 'table3', ..., 'table72']   
df_arr = [] 
[df_arr.append(pd.read_sql_query('select * from "' + table + '"', con=engine)) for table in sql_tables] 

df_join = reduce(lambda left, right: pd.merge(left, right, how='outer', on=['USER_ID']), df_arr) 
raw_dict = pd.DataFrame.to_dict(df_join.where((pd.notnull(df_join)), 'no_data')) 

print(df_join) 
print(raw_dict) 
print(len(df_arr)) 

Czy można używać Pandas dla mojego celu? Czy są lepsze rozwiązania?

Ostatecznym celem jest udostępnienie danych denormalize DB, aby można było je zindeksować do Elasticsearch jako dokumentów, po jednym dokumencie dla każdego użytkownika.

+2

Ile kolumn posiadasz we wszystkich 72 tabelach? Jeśli wynikowy DF będzie miał <= 250 kolumn, wtedy możesz i powinieneś dołączyć do PostgreSQL - nie będziesz odczuwał błędów pamięciowych – MaxU

+1

Dlaczego nie powiesz nam swojego ostatecznego celu, abyśmy mogli Ci pomóc w lepszym rozwiązaniu –

+0

@MaxU, Nie pamiętam dokładnej liczby, ale jestem pewien, że liczba kolumn jest większa niż 250. – trex

Odpowiedz

0

Nie jestem pewien, że to pomoże, ale można spróbować pd.concat

raw_dict = pd.concat([d.set_index('USER_ID') for d in df_arr], axis=1) 

Lub, aby uzyskać nieco więcej disctinction

raw_dict = pd.concat([d.set_index('USER_ID') for d in df_arr], axis=1, keys=sql_tables) 

Jeśli nie jest to pomocne, daj mi znać, a ja go usunę.

+0

Występuje następujący błąd podczas wykonywania 'pd.concat': https://gist.github.com/SergeyBondarenko/f78444f709cffec3e6777d3a16e38f2f – trex

1

Dlaczego zamiast skryptu nie utworzysz funkcji postgres?

Oto kilka porad, które mogą pomóc Ci uniknąć błędów pamięci:

  • Można użyć Z klauzulę, która sprawia, że ​​lepsze wykorzystanie pamięci.
  • Można utworzyć kilka tabel fizycznych do przechowywania informacji o różnych grupach tabel bazy danych. Te fizyczne tabele pozwolą uniknąć użycia dużej ilości pamięci. Po tym wszystkim, co musisz zrobić, to dołączyć tylko te fizyczne tabele. Możesz utworzyć dla niego funkcję.
  • Możesz utworzyć hurtownię danych, denormalizując potrzebne tabele.
  • Last but not least: Upewnij się, że używasz odpowiednio indeksów.
+0

Łączna liczba kolumn jest większa niż 1600. – trex

+0

Co, jeśli spróbujesz z hurtownią danych? –

+0

Co sugerujesz w usłudze hurtowni danych? – trex