2011-01-16 2 views
0

Ich baue eine Web-App mit Django. Ich benutze postgresql für die db. Der App-Code wird sehr unordentlich (meine Begginer-Fähigkeiten sind ein großer Faktor) und langsam, auch wenn ich die App lokal ausführe.Ist es besser, das Datenbankschema zu ändern?

Dies ist ein Auszug meiner models.py Datei:

REPEATS_CHOICES = (
    (NEVER, 'Never'), 
    (DAILY, 'Daily'), 
    (WEEKLY, 'Weekly'), 
    (MONTHLY, 'Monthly'), 
    ...some more... 
) 

class Transaction(models.Model): 
    name = models.CharField(max_length=30) 
    type = models.IntegerField(max_length=1, choices=TYPE_CHOICES) # 0 = 'Income' , 1 = 'Expense' 
    amount = models.DecimalField(max_digits=12, decimal_places=2) 
    date = models.DateField(default=date.today) 
    frequency = models.IntegerField(max_length=2, choices=REPEATS_CHOICES) 
    ends = models.DateField(blank=True, null=True) 
    active = models.BooleanField(default=True) 
    category = models.ForeignKey(Category, related_name='transactions', blank=True, null=True) 
    account = models.ForeignKey(Account, related_name='transactions') 

Das Problem ist, mit Datum, Frequenz und endet. Mit dieser Information kann ich alle Daten, in denen Transaktionen auftreten, kennen und sie verwenden, um eine Cash-Flow-Tabelle zu füllen. Auf diese Weise müssen viele Strukturen (Wörterbücher, Listen und Tupel) erstellt und oft wiederholt werden. Vielleicht gibt es eine sehr einfache Möglichkeit, dies mit dem tatsächlichen Schema zu lösen, aber ich konnte nicht realisieren, wie.

Ich denke, dass die App einfacher zu programmieren wäre, wenn ich bei der Erstellung einer Transaktion alle Daten in der Datenbank speichern könnte. Ich weiß nicht, ob es möglich ist oder ob es eine gute Idee ist.

Ich lese ein Buch über Google App Engine und die mehrwertigen Eigenschaften des Datenspeichers. Was denkst du darüber, um mein Problem zu lösen?

Edit: Ich wusste nicht über die PickleField. Ich lese jetzt darüber, vielleicht könnte ich damit alle Datetime-Objekte der Transaktion speichern.

Edit2: Dies ist ein Auszug aus meiner cashflow2 Ansicht (sorry für die schreckliche Code):

def cashflow2(request, account_name="Initial"): 

if account_name == "Initial": 
    uri = "/cashflow/new_account" 
    return HttpResponseRedirect(uri)  
month_info = {} 
cat_info = {} 
m_y_list = [] # [(month,year),] 
trans = [] 
min, max = [] , [] 

account = Account.objects.get(name=account_name, user=request.user) 
categories = account.categories.all() 
for year in range(2006,2017): 
    for month in range(1,13): 
     month_info[(month, year)] = [0, 0, 0] 
     for cat in categories: 
      cat_info[(cat, month, year)] = 0 

previous_months = 1 # previous months from actual 
next_months = 5 
dates_list = month_year_list(previous_month, next_months) # Returns [(month,year)] from the requested range 
m_y_list = [(date.month, date.year) for date in month_year_list(1,5)] 
min, max = dates_list[0], dates_list[-1] 
INCOME = 0 
EXPENSE = 1 
ONHAND = 2 
transacs_in_dates = [] 
txs = account.transactions.order_by('date') 

for tx in txs: 
    monthyear =() 
    monthyear = (tx.date.month, tx.date.year) 
    if tx.frequency == 0: 
     if tx.type == 0: 
      month_info[monthyear][INCOME] += tx.amount 
      if tx.category: 
       cat_info[(tx.category, monthyear[0], monthyear[1])] += tx.amount 
     else: 
      month_info[monthyear][EXPENSE] += tx.amount 
      if tx.category: 
       cat_info[(tx.category, monthyear[0], monthyear[1])] += tx.amount 
     if monthyear in lista_m_a: 
      if tx not in transacs_in_dates: 
       transacs_in_dates.append(tx) 
    elif tx.frequency == 4: # frequency = 'Monthly' 
     months_dif = relativedelta.relativedelta(tx.ends, tx.date).months 
     if tx.ends.day < tx.date.day: 
      months_dif += 1 
     years_dif = relativedelta.relativedelta(tx.ends, tx.date).years 
     dif = months_dif + (years_dif*12) 
     dates_range = dif + 1 
     for i in range(dates_range): 
      dt = tx.date+relativedelta.relativedelta(months=+i) 
      if (dt.month, dt.year) in m_y_list: 
       if tx not in transacs_in_dates: 
        transacs_in_dates.append(tx) 
      if tx.type == 0: 
       month_info[(fch.month,fch.year)][INCOME] += tx.amount 
       if tx.category: 
        cat_info[(tx.category, fch.month, fch.year)] += tx.amount 
      else: 
       month_info[(fch.month,fch.year)][EXPENSE] += tx.amount 
       if tx.category: 
        cat_info[(tx.category, fch.month, fch.year)] += tx.amount 

import operator 
thelist = [] 
thelist = sorted((my + tuple(v) for my, v in month_info.iteritems()), 
      key = operator.itemgetter(1, 0)) 
thelistlist = [] 
for atuple in thelist: 
    thelistlist.append(list(atuple)) 
for i in range(len(thelistlist)): 
    if i != 0: 
     thelistlist[i][4] = thelistlist[i-1][2] - thelistlist[i-1][3] + thelistlist[i-1][4] 
list = [] 
for el in thelistlist: 
    if (el[0],el[1]) in lista_m_a: 
     list.append(el) 

transactions = account.transactions.all() 

cats_in_dates_income = [] 
cats_in_dates_expense = [] 
for t in transacs_in_dates: 
    if t.category and t.type == 0: 
     if t.category not in cats_in_dates_income: 
      cats_in_dates_income.append(t.category) 
    elif t.category and t.type == 1: 
     if t.category not in cats_in_dates_expense: 
      cats_in_dates_expense.append(t.category) 

cat_infos = [] 
for k, v in cat_info.items(): 
    cat_infos.append((k[0], k[1], k[2], v)) 
+0

Definieren Sie "langsam". Und sind Sie sicher, dass die Langsamkeit durch das Erstellen von Datenstrukturen entsteht? Wie groß ist die Anzahl der Zeilen, mit denen Sie arbeiten? – AndiDog

+0

@AndiDog. Ich habe ein Konto von 7 Transaktionen und die Cashflow-Ansicht lädt in 5 Sekunden. Leistung ist nicht das wichtigste Problem, es ist der unordentliche Code. – mfalcon

+0

Ernsthaft 5 Sekunden? Dann ist es ein Fall für klassisches Druckprofilieren. Fügen Sie einfach einige 'print , time.time()' Anweisungen ein und Sie werden den Engpass sehen. Verwenden Sie den Entwicklungsserver, um die Konsolenausgabe anzuzeigen. – AndiDog

Antwort

1

Hängt davon ab, wie relevant App Engine ist hier. P.S. Wenn Sie in Essig eingelegten Objekte speichern möchten, sowie JSON-Objekte in der Google-Datenspeicher, sehen Sie sich diese beiden Code-Snippets:

http://kovshenin.com/archives/app-engine-json-objects-google-datastore/ http://kovshenin.com/archives/app-engine-python-objects- in-the-google-datastore/

Beachten Sie auch, dass der Google Datastore eine nicht-relationale Datenbank ist, so dass Sie möglicherweise andere Probleme haben, Ihren Code umzuformen, um dorthin zu wechseln.

Prost und viel Glück!