私は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))
「ゆっくり」を定義します。そして、あなたは、遅さがデータ構造の作成から来ると確信していますか?あなたが使っている行の数はどれくらいですか? – AndiDog
@AndiDog。私は7トランザクションのアカウントを持っており、キャッシュフロービューは5秒で読み込まれます。パフォーマンスは最も重要な問題ではありません。それは面倒なコードです。 – mfalcon
真剣に5秒?次に、古典的な印刷プロファイリングの場合です。いくつかの 'print、time.time()'ステートメントを挿入すると、ボトルネックが表示されます。開発サーバーを使用して、コンソール出力を確認します。 –
AndiDog