2011-01-16 9 views
0

私はdjangoでWebアプリケーションを構築しています。私はデータベースのpostgresqlを使用します。私がローカルでアプリを実行しても、アプリケーションコードは本当に乱雑になり(私の初心者のスキルは大きな要因です)、遅くなります。dbスキーマを変更する方が良いですか?

これは私のmodels.pyファイルの抜粋です。

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') 

問題は、日付、頻度と端部とです。この情報を使って、トランザクションが発生するすべての日付を知ることができ、それを使ってキャッシュフローテーブルを埋めることができます。このようにするには、多くの構造(辞書、リスト、タプル)を作成し、それらを繰り返し処理する必要があります。たぶん、実際のスキーマでこれを解決する非常に簡単な方法がありますが、私はどのように実現できませんでした。

トランザクションの作成時に、データベースにすべての日付を保存できるとすれば、アプリケーションのコード作成が簡単になると思います。私はそれが可能かどうか、それが良い考えであるかどうかは分かりません。

Googleのアプリエンジンとデータストアの複数値プロパティに関する書籍を読んでいます。私の問題を解決するためにこれについてどう思いますか?

編集:私はPickleFieldについて知りませんでした。私はそれについて読んでいます。多分、トランザクションのすべてのdatetimeオブジェクトを格納するために使用することができます。

EDIT2:これは私のcashflow2ビュー(恐ろしいコードのため申し訳ありません)の抜粋です。

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

「ゆっくり」を定義します。そして、あなたは、遅さがデータ構造の作成から来ると確信していますか?あなたが使っている行の数はどれくらいですか? – AndiDog

+0

@AndiDog。私は7トランザクションのアカウントを持っており、キャッシュフロービューは5秒で読み込まれます。パフォーマンスは最も重要な問題ではありません。それは面倒なコードです。 – mfalcon

+0

真剣に5秒?次に、古典的な印刷プロファイリングの場合です。いくつかの 'print 、time.time()'ステートメントを挿入すると、ボトルネックが表示されます。開発サーバーを使用して、コンソール出力を確認します。 – AndiDog

答えて

1

は、App Engineはここにあるどのように関連に依存します。 P.S.

http://kovshenin.com/archives/app-engine-json-objects-google-datastore/ http://kovshenin.com/archives/app-engine-python-objects-:あなたはGoogleのデータストアに漬けたオブジェクトだけでなく、JSONオブジェクトを格納したい場合は、これら2つのコードスニペットをチェックしてくださいin-the-google-datastore/

Google Datastoreは非リレーショナルデータベースなので、コードをリファクタリングしてそのデータに切り替えることができます。

乾杯!

関連する問題